📄 flagdesign.java
字号:
// !layInsts.get(0).getParent().getName().contains("infinityB"))
// return;
//
// NodeInst prev = null;
// int stretchCnt = 0;
// for (ListIterator<NodeInst> niIt=layInsts.listIterator(); niIt.hasNext();) {
// NodeInst ni = niIt.next();
// if (stretchCnt>=NUM_PLACES_TO_STRETCH) return;
// if (prev!=null && isPlain(prev) && isPlain(ni)) {
// NodeInst dumInst = LayoutLib.newNodeInst(dummyStage, 0, 0,
// DEF_SIZE, DEF_SIZE,
// 0, parent);
// niIt.add(dumInst);
// stretchCnt++;
// }
// prev = ni;
// }
// }
// infinityC needs its 2nd and 3rd stages overlapped. Same with the
// two stages next to the last stage.
private void overlapInfinityC(List<NodeInst> layInsts) {
NodeInst dataFan = layInsts.get(1);
if (!dataFan.getParent().getName().contains("infinityC"))
return;
double h = dataFan.findEssentialBounds().getHeight();
for (int i=2; i<layInsts.size(); i++) {
NodeInst ni = layInsts.get(i);
ni.move(0, -h);
}
if (true) {
for (int i=layInsts.size()-2; i<layInsts.size(); i++) {
NodeInst ni = layInsts.get(i);
ni.move(0, -h);
}
}
}
// infinityC needs stages stacked top to bottom. Furthermore,
// all stages except for the first three and last three need to be
// mirrored top <=> bottom
private void flipInfinityC(List<NodeInst> layInsts) {
NodeInst dataFan = layInsts.get(1);
if (!dataFan.getParent().getName().contains("infinityC"))
return;
Collections.reverse(layInsts);
int end = 3;
for (int i=3; i<layInsts.size()-end; i++) {
NodeInst ni = layInsts.get(i);
ni.modifyInstance(0, 0, 0, 0, Orientation.Y);
}
}
// infinityC needs scan stitched bottom to top
private void reverseScanListInfinityC(List<NodeInst> scanList) {
NodeInst first = scanList.get(1);
if (!first.getParent().getName().contains("infinityC"))
return;
Collections.reverse(scanList);
}
private NodeInst findInst(String type, List<NodeInst> insts) {
for (NodeInst ni : insts) {
String t = ni.getProto().getName();
if (t.equals(type)) return ni;
}
return null;
}
private void doInfinity(Cell autoLay, Cell schCell) {
Library autoLib = autoLay.getLibrary();
List<Library> primLibs = new ArrayList<Library>();
primLibs.add(autoLib);
SchematicVisitor visitor = new SchematicVisitor(autoLay);
HierarchyEnumerator.enumerateCell(schCell, VarContext.globalContext, visitor);
List<NodeInst> layInsts = visitor.getLayInsts();
NodeInst niA = findInst("infinityA", layInsts);
NodeInst niB = findInst("infinityB", layInsts);
NodeInst niC = findInst("infinityC", layInsts);
double colWid = niA.findEssentialBounds().getWidth();
double numFillCellsAcross = Math.ceil(colWid/config.fillCellWidth);
double columnPitch = config.fillCellWidth * numFillCellsAcross;
double spaceBetweenCols = config.fillCellWidth + columnPitch - colWid;
LayoutLib.alignCorners(niC, Corner.TL, niA, Corner.TR, -spaceBetweenCols, 0);
LayoutLib.alignCorners(niC, Corner.BR, niB, Corner.BL, spaceBetweenCols, 0);
List<ArcProto> horizLayers = new ArrayList<ArcProto>();
horizLayers.add(tech().m2());
horizLayers.add(tech().m4());
AbutRouter.abutRouteLeftRight(niA, niC, 0, horizLayers);
AbutRouter.abutRouteLeftRight(niC, niB, 0, horizLayers);
// Rectangle2D bounds = findColBounds(layInsts);
// addEssentialBounds(layInsts, bounds);
addEssentialBounds(autoLay);
ExportNamer vddNm = new ExportNamer("vdd");
ExportNamer gndNm = new ExportNamer("gnd");
//exportPwrGnd(autoLay, vddNm, gndNm);
exportPwrGnd(layInsts, vddNm, gndNm);
List<ToConnect> toConns = visitor.getLayoutToConnects();
reExport(autoLay, toConns);
}
private void doGuts(Cell autoLay, Cell schCell) {
Library autoLib = autoLay.getLibrary();
List<Library> primLibs = new ArrayList<Library>();
primLibs.add(autoLib);
SchematicVisitor visitor = new SchematicVisitor(autoLay);
HierarchyEnumerator.enumerateCell(schCell, VarContext.globalContext, visitor);
List<NodeInst> layInsts = visitor.getLayInsts();
NodeInst niI = findInst("infinity", layInsts);
NodeInst niC = findInst("crosser", layInsts);
NodeInst niR = findInst("ring", layInsts);
double colWid = niR.findEssentialBounds().getWidth();
double numFillCellsAcross = Math.ceil(colWid/config.fillCellWidth);
double columnPitch = config.fillCellWidth * numFillCellsAcross;
double spaceBetweenCols = columnPitch - colWid;
LayoutLib.alignCorners(niI, Corner.BR, niC, Corner.BL, spaceBetweenCols, (670-2));
LayoutLib.alignCorners(niC, Corner.TL, niR, Corner.BL, 0, 0);
List<ArcProto> horizLayers = new ArrayList<ArcProto>();
horizLayers.add(tech().m2());
horizLayers.add(tech().m4());
AbutRouter.abutRouteLeftRight(niI, niC, 0, horizLayers);
AbutRouter.abutRouteLeftRight(niI, niR, 0, horizLayers);
}
private boolean portOnLayer(PortInst pi, List<ArcProto> layers) {
for (ArcProto ap : layers) {
if (pi.getPortProto().connectsTo(ap)) return true;
}
return false;
}
private void exportPwrGnd(List<NodeInst> stages,
ExportNamer vdd, ExportNamer gnd) {
Rectangle2D colBounds = Utils.findBounds(stages.get(0).getParent());
List<ArcProto> vertLayers = new ArrayList<ArcProto>();
vertLayers.add(tech().m3());
List<ArcProto> horiLayers = new ArrayList<ArcProto>();
horiLayers.add(tech().m2());
for (NodeInst ni : stages) {
for (Iterator piIt=ni.getPortInsts(); piIt.hasNext();) {
PortInst pi = (PortInst) piIt.next();
if (Utils.isPwrGnd(pi)) {
if ((Utils.onTopOrBottom(pi, colBounds, 0) &&
portOnLayer(pi, vertLayers)) ||
(Utils.onLeftOrRight(pi, colBounds, 0) &&
portOnLayer(pi, horiLayers))) {
Cell parent = pi.getNodeInst().getParent();
String exptNm;
if (Utils.isPwr(pi)) {
exptNm = vdd.nextName();
} else {
exptNm = gnd.nextName();
}
Export.newInstance(parent, pi, exptNm);
}
}
}
}
}
// Re-export all PortInsts of all NodeInsts that have the power or ground
// characteristic that aren't connected to arcs.
private void exportPwrGnd(Cell c, ExportNamer vdd, ExportNamer gnd) {
for (Iterator<NodeInst> niIt=c.getNodes(); niIt.hasNext();) {
NodeInst ni = niIt.next();
if (!(ni.getProto() instanceof Cell)) continue;
for (Iterator<PortInst> piIt=ni.getPortInsts(); piIt.hasNext();) {
PortInst pi = piIt.next();
if (!Utils.isPwrGnd(pi)) continue;
if (pi.hasConnections()) continue;
Export e;
if (Utils.isPwr(pi)) {
e = Export.newInstance(c, pi, vdd.nextName());
e.setCharacteristic(PortCharacteristic.PWR);
} else {
e = Export.newInstance(c, pi, gnd.nextName());
e.setCharacteristic(PortCharacteristic.GND);
}
}
}
}
// private void doInfinityABC(Cell autoLay, Cell schCell) {
// List<NodeInst> layInsts = new ArrayList<NodeInst>();
// List<ToConnect> toConns = new ArrayList<ToConnect>();
// LayoutNetlist layNets = createLayInstsFromSch(autoLay, schCell);
//
// flipInfinityC(layInsts);
// stackLayInsts(layInsts);
// overlapInfinityC(layInsts);
//
//// Rectangle2D colBounds = findColBounds(layInsts);
//// addEssentialBounds(layInsts, colBounds);
// addEssentialBounds(autoLay);
// router.connectPwrGnd(layInsts);
//
// List<NodeInst> scanList = new ArrayList<NodeInst>(layInsts);
// reverseScanListInfinityC(scanList);
// scan.stitchScanChains(scanList, router);
//
// // debug
// //for (ToConnect cl : toConns) prln(" N-Pin "+cl.toString());
//
// //List<ToConnect> twoPins = reduceToTwoPin(toConns);
//// List<ToConnect> twoOrThreePins = reduceToTwoOrThreePin(toConns);
////
//// LayerChannels m2chan = new LayerChannels();
//// LayerChannels m3chan = new LayerChannels();
////
//// findChannels(m2chan, m3chan, layInsts);
////
//// route(twoOrThreePins, m2chan, m3chan);
//
//// List<NodeInst> covers = coverWithContacts(layInsts);
//// //exportVddGndCover(vddCnt, gndCnt, covers);
//// List<ArcProto> m3Layer = new ArrayList<ArcProto>();
//// m3Layer.add(tech().m3());
//// AbutRouter.abutRouteBotTop(covers.get(0), layInsts.get(0), 0, m3Layer);
//
// ExportNamer vddNmr = new ExportNamer("vdd");
// ExportNamer gndNmr = new ExportNamer("gnd");
// //exportPwrGnd(autoLay, vddNmr, gndNmr);
// exportPwrGnd(layInsts, vddNmr, gndNmr);
// //fattenPwrGnd(layInsts);
//
// // Debug
// //dumpChannels(m2chan, m3chan);
//
// System.out.println("done.");
// }
/** If any PortInst is a scan port then ToConnect is a scan ToConnect */
boolean isScanToConnect(ToConnect tc) {
for (PortInst pi : tc.getPortInsts()) {
if (scan.isScan(pi)) return true;
}
return false;
}
private List<ToConnect> selectScanToConnects(List<ToConnect> toConns) {
List<ToConnect> scans = new ArrayList<ToConnect>();
for (ToConnect tc : toConns) if (isScanToConnect(tc)) scans.add(tc);
// debug
for (ToConnect tc : scans) {
prln("selectScanToCOnnects: "+tc.toString());
}
return scans;
}
private List<ToConnect> selectSignalToConnects(List<ToConnect> toConns) {
List<ToConnect> signals = new ArrayList<ToConnect>();
for (ToConnect tc : toConns) {
if (isScanToConnect(tc)) continue;
if (Utils.isPwrGnd(tc)) continue;
signals.add(tc);
}
return signals;
}
// --------------------- methods for physical designers -------------------
protected FlagDesign(FlagConfig cfg, FlagConstructorData data) {
this.config = cfg;
scan = new Scan(config.chains, cfg);
router = new Router(config, scan);
sogRouterAdapter = new SogRouterAdapter(data.getJob());
}
protected static void prln(String s) {Utils.prln(s);}
protected static void pr(String s) {Utils.pr(s);}
protected static void error(boolean cond, String msg) {Utils.error(cond, msg);}
protected void addEssentialBounds(Cell c) {
Rectangle2D bounds = Utils.findBounds(c);
LayoutLib.newNodeInst(tech().essentialBounds(),
bounds.getMinX(),
bounds.getMinY(),
DEF_SIZE, DEF_SIZE, 180, c);
LayoutLib.newNodeInst(tech().essentialBounds(),
bounds.getMaxX(),
bounds.getMaxY(),
DEF_SIZE, DEF_SIZE, 0, c);
}
/** Traverse schematic hierarchy. For each instance of primitive Cell
* in the schematic, instantiate the layout of that primitive Cell in
* the layout. Return a list of the layout
* instances sorted by y coordinate of corresponding schematic instances. */
protected LayoutNetlist createLayoutInstancesFromSchematic(FlagConstructorData data) {
Cell layCell = data.getLayoutCell();
Cell schCell = data.getSchematicCell();
SchematicVisitor visitor = new SchematicVisitor(layCell);
HierarchyEnumerator.enumerateCell(schCell, VarContext.globalContext, visitor);
List<NodeInst> sortedLayInsts = getSortedLayInsts(visitor);
printInstanceReport(sortedLayInsts);
return new LayoutNetlist(layCell, sortedLayInsts,
visitor.getLayoutToConnects());
}
protected void stitchScanChains(LayoutNetlist layNets) {
scan.stitchScanChains(layNets.getLayoutInstancesSortedBySchematicPosition(), router);
}
protected void stitchScanChainsSog(LayoutNetlist layNets) {
List<ToConnect> scans = selectScanToConnects(layNets.getToConnects());
sogRouterAdapter.route(scans);
}
protected void routeSignalsSog(List<ToConnect> toConns) {
List<ToConnect> signals = selectSignalToConnects(toConns);
sogRouterAdapter.route(signals);
}
protected void routeSignals(LayoutNetlist layNets) {
List<ToConnect> signals = selectSignalToConnects(layNets.getToConnects());
router.routeSignals(signals, layNets);
}
protected void reexportPowerGround(Cell c) {
List<Geometric> allNodes = new ArrayList<Geometric>();
for (Iterator<NodeInst> it = c.getNodes(); it.hasNext(); ) {
allNodes.add(it.next());
}
int num = ExportChanges.reExportNodes(c, allNodes, false, true, true, true);
}
protected void reexportSignals(LayoutNetlist layNets) {
Cell layCell = layNets.getLayoutCell();
List<ToConnect> toConns = layNets.getToConnects();
reExport(layCell, toConns);
}
protected void addNccVddGndExportsConnectedByParent(Cell c) {
NccCellAnnotations.addNccAnnotation(c, "exportsConnectedByParent vdd /vdd_[0-9]+/");
NccCellAnnotations.addNccAnnotation(c, "exportsConnectedByParent gnd /gnd_[0-9]+/");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -