/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: LocalPartitioning.java * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */ package com.sun.electric.tool.ncc.processing; import java.util.ArrayList; import java.util.List; import java.util.Set; import com.sun.electric.tool.ncc.NccGlobals; import com.sun.electric.tool.ncc.lists.LeafList; import com.sun.electric.tool.ncc.netlist.NetObject; import com.sun.electric.tool.ncc.netlist.Part; import com.sun.electric.tool.ncc.netlist.Wire; import com.sun.electric.tool.ncc.strategy.StratHashParts; import com.sun.electric.tool.ncc.strategy.StratHashWires; import com.sun.electric.tool.ncc.strategy.StratPartPopularity; import com.sun.electric.tool.ncc.strategy.StratPartType; import com.sun.electric.tool.ncc.strategy.Strategy; import com.sun.electric.tool.ncc.trees.EquivRecord; /** LocalPartitioning partitions the Part and Wire equivalence classes based * on purely local characteristics. In principle, these partitions are * redundant with the normal hash code process. However it seems useful * to perform these first because: * 1) There is no hash code computation. Therefore errors in one part of * the circuit do not cause mismatches in other parts of the circuit. * 2) They can be easily explained to the user. */ public class LocalPartitioning { private static class GetLeaves extends Strategy { List<EquivRecord> matched = new ArrayList<EquivRecord>(); List<EquivRecord> notMatched = new ArrayList<EquivRecord>(); GetLeaves(EquivRecord er, NccGlobals glob) { super(glob); if (er!=null) doFor(er); } @Override public LeafList doFor(EquivRecord er) { if (er.isLeaf()) { if (er.isMatched()) matched.add(er); else notMatched.add(er); } else { return super.doFor(er); } return new LeafList(); } public List<EquivRecord> getMatched() {return matched;} public List<EquivRecord> getNotMatched() {return notMatched;} } NccGlobals globals; /** return a Set of all the types of Pins we might encounter */ private void partitionPartsUsingLocalInformation(Set<Part> forcedMatchParts) { globals.status2("Partition Parts using local information"); if (globals.getParts()==null) return; LeafList offspring = StratPartType.doYourJob(forcedMatchParts, globals); if (offspring.size()!=0) { //StratCheck.doYourJob(globals.getRoot(), globals); //StratCount.doYourJob(globals.getRoot(), globals); } offspring = StratPartPopularity.doYourJob(forcedMatchParts, globals); if (offspring.size()!=0) { //StratCheck.doYourJob(globals.getRoot(), globals); //StratCount.doYourJob(globals.getRoot(), globals); } } private LocalPartitioning(NccGlobals globals) {this.globals = globals;} private void localPartitionPartsAndWires(Set<Part> forcedMatchParts, Set<Wire> forcedMatchWires) { globals.status2("Begin partitioning based on local characteristics \n"); partitionPartsUsingLocalInformation(forcedMatchParts); LocalPartitionWires.doYourJob(forcedMatchWires, globals); /* Count EquivRecords after Local Partitioning */ /* int numMatchedPartRecs = globals.getPartLeafEquivRecs().numMatched(); int numNotMatchedPartRecs = globals.getPartLeafEquivRecs().numNotMatched(); int numMatchedWireRecs = globals.getWireLeafEquivRecs().numMatched(); int numNotMatchedWireRecs = globals.getWireLeafEquivRecs().numNotMatched(); System.out.println("Local Partitioning Results: #matchedPartRecs="+numMatchedPartRecs+ " #notMatchedPartRecs="+numNotMatchedPartRecs+ " #matchedWireRecs="+numMatchedWireRecs+ " #notMatchedWireRecs="+numNotMatchedWireRecs); */ //StratReportLocalPartitionFailure.doYourJob(globals); globals.status2("End partitioning based on local characteristics "); } /** Subtle!!!: If user has forced the match of Parts or Wires then * we MUST check, via hashing, all Parts and Wires that were matched * by Local Partitioning. Otherwise we may fail to report mismatches. * Report Parts and Wires matched by LocalPartitioning but subsequently * mismatched by hashing as "hash code" errors. */ private LocalPartitionResult hashMatchedPartsWires(Set<Part> forcedMatchParts, Set<Wire> forcedMatchWires) { GetLeaves partLeaves = new GetLeaves(globals.getParts(), globals); GetLeaves wireLeaves = new GetLeaves(globals.getWires(), globals); LocalPartitionResult lpr = new LocalPartitionResult(partLeaves.getNotMatched(), wireLeaves.getNotMatched(), globals); List<EquivRecord> partsToCheck = new ArrayList<EquivRecord>(); for (EquivRecord er : partLeaves.getMatched()) { NetObject no = er.getCircuits().next().getNetObjs().next(); if (!forcedMatchParts.contains(no)) partsToCheck.add(er); } List<EquivRecord> wiresToCheck = new ArrayList<EquivRecord>(); for (EquivRecord er : wireLeaves.getMatched()) { NetObject no = er.getCircuits().next().getNetObjs().next(); if (!forcedMatchWires.contains(no)) wiresToCheck.add(er); } StratHashParts.doYourJob(partsToCheck.iterator(), globals); StratHashWires.doYourJob(wiresToCheck.iterator(), globals); return lpr; } // ------------------------ public method --------------------------------- /** Partition Parts and wires based upon purely local information. * We pass in the Parts and Wires that have been pre-matched because * those Parts and Wires may actually mismatch and we must prevent * LocalPartitioning from mismatching them. * @param forcedMatchParts Parts that have been pre-matched by the user * @param forcedMatchWires Wires that have been pre-matched by the user * @param globals variables shared by all parts of NCC */ public static LocalPartitionResult doYourJob(Set<Part> forcedMatchParts, Set<Wire> forcedMatchWires, NccGlobals globals) { LocalPartitioning jsl = new LocalPartitioning(globals); jsl.localPartitionPartsAndWires(forcedMatchParts, forcedMatchWires); return jsl.hashMatchedPartsWires(forcedMatchParts, forcedMatchWires); } }