/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: CompareLists.java * * Copyright (c) 2003 Sun Microsystems and 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.basic; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import com.sun.electric.database.hierarchy.Cell; import com.sun.electric.database.hierarchy.Cell.CellGroup; import com.sun.electric.tool.Job; /** * A collection of one or more CompareLists. NCC will sequence * through each CompareList making sure that Cells in the same * CompareList are topologically identical. The collection is ordered * so that NCC will begin with leaf Cells first and proceed upwards * in the design hierarchy towards the root. */ public class CompareLists { // Subtle!!!: alreadyCompared tests Cells rather than CellContexts // Suppose the root Cells being compared are A and B. Suppose A // instantiates B. Suppose we happen to scan the Cells in A in order // to build compare lists. When B is used as the seed it will form // a compare list of (B, A-as-root context), (B, B-as-root), // and (A, A-as-root). Then purgeUnnecessaryDuplicateCells() will // remove one of the B CellContexts: say it keeps (B, A-as-root). // Next we build a compare list // using A as the seed. The compare list is (A, A-as-root) and // (B, B-as-root). Thus two compare lists have the same Cells. // alreadyCompared is supposed to purge the second list. Instead // it throws an exception "cell group partially processed" because // the A CellContext is in "compared" but the B CellContext isn't. private boolean alreadyCompared(Set compared, CompareList compareList) { int num=0, numComp=0; for (Iterator<CellContext> it=compareList.iterator(); it.hasNext();) { CellContext cc = it.next(); if (compared.contains(cc.cell)) { numComp++; // RKao debug //System.out.println("already did: "+cc.cell.getName()); } num++; } Job.error(numComp!=0 && numComp!=num, "cell group partially processed"); return numComp>0; } private List<CompareList> getCompareLists(CellUsage use1, CellUsage use2) { Set<Cell> compared = new HashSet<Cell>(); Set<CellGroup> visitedGroups = new HashSet<CellGroup>(); List<CompareList> compareLists = new ArrayList<CompareList>(); for (Iterator<Cell> it=use1.cellsInReverseTopologicalOrder(); it.hasNext();) { Cell cell = it.next(); // RKao debug //System.out.println("seed cell: "+cell.getName()); CompareList compareList = new CompareList(cell, use1, use2, visitedGroups); // RKao debug //compareList.printCells(); // Really subtle! If A instantiates B and B instantiates C and if A, B, // and C are all in the same Cell group then this loop will encounter // the Cell group {A, B, C} three times! Only perform the comparison // once. if (alreadyCompared(compared, compareList)) continue; if (compareList.empty()) continue; for (Iterator<CellContext> it2=compareList.iterator(); it2.hasNext();) { CellContext cc = it2.next(); compared.add(cc.cell); } compareLists.add(compareList); } return compareLists; } private List<CompareList> getCompareLists1(CellContext cc1, CellContext cc2) { CellUsage use1 = CellUsage.getCellUsage(cc1); CellUsage use2 = CellUsage.getCellUsage(cc2); return getCompareLists(use1, use2); } /** Scan the two designs, cc1 and cc2 to produce a list of * CompareLists. Typically, cc1 is the schematic and cc2 is the layout. * The CompareLists are ordered * starting with the leaf cells. * @param cc1 the root Cell and VarContext of the first design * @param cc2 the root Cell and VarContext of the second design * @return A CompareLists object which is a collection of CompareLists. */ public static List<CompareList> getCompareLists(CellContext cc1, CellContext cc2) { return (new CompareLists()).getCompareLists1(cc1, cc2); } }