📄 fillgeneratortool.java
字号:
public FillGeneratorTool() { super("Fill Generator"); } public void setConfig(FillGenConfig config) { this.config = config; this.libInitialized = false; /** Set technology */ Tech.setTechType(config.techType.getTechType()); } public enum Units {NONE, LAMBDA, TRACKS} protected boolean getOrientation() {return plans[plans.length-1].horizontal;} /** Reserve space in the middle of the Vdd and ground straps for signals. * @param layer the layer number. This may be 2, 3, 4, 5, or 6. The layer * number 1 is reserved to mean "capacitor between Vdd and ground". * @param reserved space to reserve in the middle of the central * strap in case of Vdd. The value 0 makes the Vdd strap one large strap instead of two smaller * adjacent straps. * Space to reserve between the ground strap of this * cell and the ground strap of the adjacent fill cell. The value 0 means * that these two ground straps should abut to form a single large strap * instead of two smaller adjacent straps. * */ private double reservedToLambda(int layer, double reserved, Units units) { if (units==LAMBDA) return reserved; double nbTracks = reserved; if (nbTracks==0) return 0; return config.techType.getTechType().reservedToLambda(layer, nbTracks); } private Floorplan[] makeFloorplans(boolean metalFlex, boolean hierFlex) { LayoutLib.error(config.width==Double.NaN, "width hasn't been specified. use setWidth()"); LayoutLib.error(config.height==Double.NaN, "height hasn't been specified. use setHeight()"); double w = config.width; double h = config.height; int numLayers = config.techType.getTechType().getNumMetals() + 1; // one extra for the cap double[] vddRes = new double[numLayers]; //{0,0,0,0,0,0,0}; double[] gndRes = new double[numLayers]; //{0,0,0,0,0,0,0}; double[] vddW = new double[numLayers]; //{0,0,0,0,0,0,0}; double[] gndW = new double[numLayers]; //{0,0,0,0,0,0,0}; // set given values for (FillGenConfig.ReserveConfig c : config.reserves) { vddRes[c.layer] = reservedToLambda(c.layer, c.vddReserved, c.vddUnits); gndRes[c.layer] = reservedToLambda(c.layer, c.gndReserved, c.gndUnits); if (c.vddWUnits != Units.NONE) vddW[c.layer] = reservedToLambda(c.layer, c.vddWidth, c.vddWUnits); if (c.gndWUnits != Units.NONE) gndW[c.layer] = reservedToLambda(c.layer, c.gndWidth, c.gndWUnits); } boolean evenHor = config.evenLayersHorizontal; boolean alignedMetals = true; double[] spacing = new double[numLayers]; for (int i = 0; i < numLayers; i++) spacing[i] = config.drcSpacingRule;// {config.drcSpacingRule,config.drcSpacingRule,// config.drcSpacingRule,config.drcSpacingRule,// config.drcSpacingRule,config.drcSpacingRule,config.drcSpacingRule}; if (alignedMetals) { double maxVddRes = 0, maxGndRes = 0, maxSpacing = 0, maxVddW = 0, maxGndW = 0; for (int i = 0; i < vddRes.length; i++) { boolean vddOK = false, gndOK = false; if (vddRes[i] > 0) { vddOK = true; if (maxVddRes < vddRes[i]) maxVddRes = vddRes[i]; } if (gndRes[i] > 0) { gndOK = true; if (maxGndRes < gndRes[i]) maxGndRes = gndRes[i]; } if (gndOK || vddOK) // checking max spacing rule { if (maxSpacing < config.drcSpacingRule) maxSpacing = config.drcSpacingRule; //drcRules[i]; } if (maxVddW < vddW[i]) maxVddW = vddW[i]; if (maxGndW < gndW[i]) maxGndW = gndW[i]; } // correct the values for (int i = 0; i < vddRes.length; i++) { vddRes[i] = maxVddRes; gndRes[i] = maxGndRes; spacing[i] = maxSpacing; vddW[i] = maxVddW; gndW[i] = maxGndW; } } Floorplan[] thePlans = new Floorplan[numLayers]; // 0 is always null thePlans[1] = new CapFloorplan(w, h, !evenHor); if (metalFlex) { if (!hierFlex) { for (int i = 2; i < numLayers; i++) { boolean horiz = (i%2==0); thePlans[i] = new MetalFloorplanFlex(w, h, vddRes[i], gndRes[i], spacing[i], vddW[i], gndW[i], horiz); } return thePlans; } w = config.width = config.minTileSizeX; h = config.height = config.minTileSizeY; } for (int i = 2; i < numLayers; i++) { boolean horiz = (i%2==0); thePlans[i] = new MetalFloorplan(w, h, vddRes[i], gndRes[i], spacing[i], horiz); } return thePlans; } private void printCoverage(Floorplan[] plans) { for (int i=2; i<plans.length; i++) { System.out.println("metal-"+i+" coverage: "+ ((MetalFloorplan)plans[i]).coverage); } } private static CapCell getCMOS90CapCell(Library lib, CapFloorplan plan) { CapCell c = null; try { Class<?> cmos90Class = Class.forName("com.sun.electric.plugins.tsmc.fill90nm.CapCellCMOS90"); Constructor capCellC = cmos90Class.getDeclaredConstructor(Library.class, CapFloorplan.class); // varargs Object cell = capCellC.newInstance(lib, plan); c = (CapCell)cell; } catch (Exception e) { assert(false); // runtime error } return c; } protected void initFillParameters(boolean metalFlex, boolean hierFlex) { if (libInitialized) return; LayoutLib.error(config.fillLibName==null, "no library specified. Use setFillLibrary()"); LayoutLib.error((config.width==Double.NaN || config.width<=0), "no width specified. Use setFillCellWidth()"); LayoutLib.error((config.height==Double.NaN || config.height<=0), "no height specified. Use setFillCellHeight()"); plans = makeFloorplans(metalFlex, hierFlex); if (!metalFlex) printCoverage(plans); lib = LayoutLib.openLibForWrite(config.fillLibName); if (!metalFlex) // don't do transistors { if (config.techType == TechType.TechTypeEnum.MOCMOS || config.techType == TechType.TechTypeEnum.TSMC180) { capCell = new CapCellMosis(lib, (CapFloorplan) plans[1]); } else { capCell = getCMOS90CapCell(lib, (CapFloorplan) plans[1]); } } libInitialized = true; } private void makeTiledCells(Cell cell, Floorplan[] plans, Library lib, int[] tiledSizes) { if (tiledSizes==null) return; for (int num : tiledSizes) { TiledCell.makeTiledCell(num, num, cell, plans, lib); } } public static Cell makeFillCell(Library lib, Floorplan[] plans, int botLayer, int topLayer, CapCell capCell, TechType tech, ExportConfig expCfg, boolean metalFlex, boolean hierFlex) { FillCell fc = new FillCell(tech); return fc.makeFillCell1(lib, plans, botLayer, topLayer, capCell, expCfg, metalFlex, hierFlex); } /** * Method to create standard set of tiled cells. */ private Cell standardMakeAndTileCell(Library lib, Floorplan[] plans, int lowLay, int hiLay, CapCell capCell, TechType tech, ExportConfig expCfg, int[] tiledSizes, boolean metalFlex) { Cell master = makeFillCell(lib, plans, lowLay, hiLay, capCell, tech, expCfg, metalFlex, false); masters = new ArrayList<Cell>(); masters.add(master); makeTiledCells(master, plans, lib, tiledSizes); return master; } public static final Units LAMBDA = Units.LAMBDA; public static final Units TRACKS = Units.TRACKS; //public static final PowerType POWER = PowerType.POWER; //public static final PowerType VDD = PowerType.VDD; public static final ExportConfig PERIMETER = ExportConfig.PERIMETER; public static final ExportConfig PERIMETER_AND_INTERNAL = ExportConfig.PERIMETER_AND_INTERNAL; /** Reserve space in the middle of the Vdd and ground straps for signals. * @param layer the layer number. This may be 2, 3, 4, 5, or 6. The layer * number 1 is reserved to mean "capacitor between Vdd and ground". * @param vddReserved space to reserve in the middle of the central Vdd * strap. * The value 0 makes the Vdd strap one large strap instead of two smaller * adjacent straps. * @param vddUnits LAMBDA or TRACKS * @param gndReserved space to reserve between the ground strap of this * cell and the ground strap of the adjacent fill cell. The value 0 means * that these two ground straps should abut to form a single large strap * instead of two smaller adjacent straps. * @param gndUnits LAMBDA or TRACKS * param tiledSizes an array of sizes. The default value is null. The * value null means don't generate anything. */// public void reserveSpaceOnLayer(int layer,// double vddReserved, Units vddUnits,// double gndReserved, Units gndUnits) {// LayoutLib.error(layer<2 || layer>6,// "Bad layer. Layers must be between 2 and 6 inclusive: "+// layer);// this.vddReserved[layer] = reservedToLambda(layer, vddReserved, vddUnits);// this.gndReserved[layer] = reservedToLambda(layer, gndReserved, gndUnits);// } /** Create a fill cell using the current library, fill cell width, fill cell * height, layer orientation, and reserved spaces for each layer. Then * generate larger fill cells by tiling that fill cell according to the * current tiled cell sizes. * @param loLayer the lower layer. This may be 1 through 6. Layer 1 means * build a capacitor using MOS transistors between Vdd and ground. * @param hiLayer the upper layer. This may be 2 through 6. Note that hiLayer * must be >= loLayer. * @param exportConfig may be PERIMETER in which case exports are * placed along the perimeter of the cell for the top two layers. Otherwise * exportConfig must be PERIMETER_AND_INTERNAL in which case exports are * placed inside the perimeter of the cell for the bottom layer. * @param tiledSizes Array specifying composite Cells we should build by * concatonating fill cells. For example int[] {2, 4, 7} means we should * */ public Cell standardMakeFillCell(int loLayer, int hiLayer, TechType tech, ExportConfig exportConfig, int[] tiledSizes, boolean metalFlex) { initFillParameters(metalFlex, false); LayoutLib.error(loLayer<1, "loLayer must be >=1"); int maxNumMetals = config.techType.getTechType().getNumMetals(); LayoutLib.error(hiLayer>maxNumMetals, "hiLayer must be <=" + maxNumMetals); LayoutLib.error(loLayer>hiLayer, "loLayer must be <= hiLayer"); Cell cell = null; cell = standardMakeAndTileCell(lib, plans, loLayer, hiLayer, capCell, tech, exportConfig, tiledSizes, metalFlex); return cell; } public void makeGallery() { Gallery.makeGallery(lib); } public void writeLibrary() { LayoutLib.writeLibrary(lib); } public enum FillTypeEnum {INVALID,TEMPLATE,CELL}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -