⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spiceparasitic.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		{
			if (shortedExports.size() > 1)
				curSegmentedNets.addShortedExports(shortedExports);
		}
	}

	/**
	 * Method to emit the name of a signal on an instance call (the "X" statement).
	 * @param no the Nodable for the cell instance being examined.
	 * @param subNet the Network in the cell attached to that Nodable.
	 * @param subSegmentedNets the SpiceSegmentedNets object for the Nodable's Cell.
	 * @param infstr the string buffer in which to emit the name(s).
	 */
	public void getParasiticName(Nodable no, Network subNet, SpiceSegmentedNets subSegmentedNets, StringBuffer infstr)
	{
		// connect to all exports (except power and ground of subcell net)
		List<String> exportNames = new ArrayList<String>();
		for (Iterator<Export> it = subNet.getExports(); it.hasNext(); )
		{
			// get subcell export, unless collapsed due to less than min R
			Export e = it.next();
			PortInst pi = e.getOriginalPort();
			String name = subSegmentedNets.getNetName(pi);
			if (exportNames.contains(name)) continue;
			exportNames.add(name);

			// ok, there is a port on the subckt on this subcell for this export,
			// now get the appropriate network in this cell
			pi = no.getNodeInst().findPortInstFromProto(no.getProto().findPortProto(e.getNameKey()));
			name = curSegmentedNets.getNetName(pi);
			infstr.append(" " + name);
		}
	}

	/**
	 * Method to find the SpiceSegmentedNets object that corresponds to a given Cell.
	 * @param cell the Cell to find.
	 * @return the SpiceSegmentedNets object associated with that cell (null if none found).
	 */
	public SpiceSegmentedNets getSegmentedNets(Cell cell)
	{
		for (SpiceSegmentedNets seg : segmentedParasiticInfo)
			if (seg.getCell() == cell) return seg;
		return null;
	}

	/**
	 * Method called at the end of netlist writing to deal with back-annotation.
	 */
	public void backAnnotate()
	{
    	Set<Cell>      cellsToClear = new HashSet<Cell>();
    	List<PortInst> capsOnPorts  = new ArrayList<PortInst>();
    	List<String>   valsOnPorts  = new ArrayList<String>();
    	List<ArcInst>  resOnArcs    = new ArrayList<ArcInst>();
    	List<Double>   valsOnArcs   = new ArrayList<Double>();
        for (SpiceSegmentedNets segmentedNets : segmentedParasiticInfo)
        {
            Cell cell = segmentedNets.getCell();
            if (cell.getView() != View.LAYOUT) continue;

            // gather cells to clear capacitor values
            cellsToClear.add(cell);

            // gather capacitor updates
            for (SpiceSegmentedNets.NetInfo info : segmentedNets.getUniqueSegments())
            {
                PortInst pi = info.getPortIterator().next();
                if (info.getCap() > cell.getTechnology().getMinCapacitance())
                {
                	capsOnPorts.add(pi);
                	valsOnPorts.add(TextUtils.formatDouble(info.getCap(), 2) + "fF");
                }
            }

            // gather resistor updates
            for (Iterator<ArcInst> it = cell.getArcs(); it.hasNext(); )
            {
                ArcInst ai = it.next();
                Double res = segmentedNets.getRes(ai);

                resOnArcs.add(ai);
                valsOnArcs.add(res);
            }
        }
        new BackAnnotateJob(cellsToClear, capsOnPorts, valsOnPorts, resOnArcs, valsOnArcs);
	}

	/**
	 * Class to run back-annotation in a Job.
	 */
	private static class BackAnnotateJob extends Job
    {
    	private Set<Cell> cellsToClear;
    	private List<PortInst> capsOnPorts;
    	private List<String> valsOnPorts;
    	private List<ArcInst> resOnArcs;
    	private List<Double> valsOnArcs;

        private BackAnnotateJob(Set<Cell> cellsToClear, List<PortInst> capsOnPorts, List<String> valsOnPorts,
        	List<ArcInst> resOnArcs, List<Double> valsOnArcs)
    	{
            super("Spice Layout Back Annotate", User.getUserTool(), Job.Type.CHANGE, null, null, Job.Priority.USER);
            this.capsOnPorts = capsOnPorts;
            this.valsOnPorts = valsOnPorts;
            this.resOnArcs = resOnArcs;
            this.valsOnArcs = valsOnArcs;
            this.cellsToClear = cellsToClear;
            startJob();
        }

        public boolean doIt() throws JobException
        {
            TextDescriptor ctd = TextDescriptor.getPortInstTextDescriptor().withDispPart(TextDescriptor.DispPos.NAMEVALUE);
            TextDescriptor rtd = TextDescriptor.getArcTextDescriptor().withDispPart(TextDescriptor.DispPos.NAMEVALUE);
            int capCount = 0;
            int resCount = 0;

            // clear caps on layout
            for(Cell cell : cellsToClear)
            {
                // delete all C's already on layout
                for (Iterator<NodeInst> it = cell.getNodes(); it.hasNext(); )
                {
                    NodeInst ni = it.next();
                    for (Iterator<PortInst> pit = ni.getPortInsts(); pit.hasNext(); )
                    {
                        PortInst pi = pit.next();
                        Variable var = pi.getVar(ATTR_C);
                        if (var != null) pi.delVar(var.getKey());
                    }
                }
            }

            // add new C's
            for(int i=0; i<capsOnPorts.size(); i++)
            {
            	PortInst pi = capsOnPorts.get(i);
            	String str = valsOnPorts.get(i);
                pi.newVar(ATTR_C, str, ctd);
                resCount++;
            }

            // add new R's
            for(int i=0; i<resOnArcs.size(); i++)
            {
            	ArcInst ai = resOnArcs.get(i);
            	Double res = valsOnArcs.get(i);

                // delete R if no new one
                Variable var = ai.getVar(ATTR_R);
                if (res == null && var != null)
                    ai.delVar(ATTR_R);

                // change R if new one
                if (res != null)
                {
                    ai.newVar(ATTR_R, res, rtd);
                    resCount++;
                }
            }
            System.out.println("Back-annotated "+resCount+" Resistors and "+capCount+" Capacitors");
            return true;
        }
    }
	
	/**
	 * Method to print the netlist considering the metal lines as distribute RC(transmission lines) 
	 */
	public void writeNewSpiceCode(Cell cell,CellNetInfo cni,Technology layoutTechnology, Spice out)
	{
		double scale = layoutTechnology.getScale(); 

		networkList = new ArrayList<Network>();
		arcList = new ArrayList<ArcInst>();

		for (SpiceSegmentedNets segmentedNets : segmentedParasiticInfo)
        {
			if (segmentedNets.getCell() != cell) continue;   
			for( Iterator<Network> itNet = cni.getNetList().getNetworks();itNet.hasNext();)
			{
				Network net = itNet.next();
				Iterator<ArcInst> itArc = net.getArcs();
				ArcInst FirstAi = itArc.next();
			
            	double sqrs =0;
        		double cap=0;
        		double res=0;
        		boolean startAgain=false;
        
                ArcInst MainAi = FirstAi;
                ArcInst CurrAi = MainAi;
                
                // Start with the head port instance of the first arc
                Iterator<Connection> ConIT = MainAi.getHeadPortInst().getConnections();
                PortInst MainPI = MainAi.getHeadPortInst();
                n0 = segmentedNets.getNetName(MainAi.getHeadPortInst());
                
                // If this network is not already analyzed
                if (networkList == null || !networkList.contains(net))
                {
                	networkList.add(net);
                   	while(ConIT.hasNext())
                	{
                   		Connection conn = ConIT.next();
                		CurrAi = conn.getArc();
                		
                		// If this arc is not already analyzed.
                		if (!arcList.contains(CurrAi))
                		{
                			double length = CurrAi.getLambdaLength() * scale / 1000;          // length in microns
                    		double width = CurrAi.getLambdaBaseWidth() * scale / 1000;        // width in microns
                			Poly[] polya = layoutTechnology.getShapeOfArc(CurrAi);
                    		Poly poly = polya[0];
                    		if (poly.isPseudoLayer()) continue;
                    		String curLayer = poly.getLayer().getName();
                    		
                    		// If both the arcs are of the same layer ,add resistance, 
                    		// capacitance and no. of squares and continue traversing.
                    		// Else print the existing data and start afresh.
                			if((preLayer == curLayer) || preLayer == "") {
                				preLayer = curLayer;
                				arcList.add(CurrAi);
                				sqrs += length / width;
                    	   		res += segmentedNets.getRes(CurrAi).doubleValue();
                    	   		cap += segmentedNets.getArcCap(CurrAi);
                			} else {
                				preLayer = curLayer;
                				arcList.add(null);
                				arcList.add(CurrAi);
                				if(sqrs > 3)
                				{
                					out.multiLinePrint(false, "XP" + tLineCount + " " + n0 + " " + n1 +" RCLINE R=" + TextUtils.formatDouble(res/sqrs, 2) + " C=" + TextUtils.formatDouble(cap/sqrs, 2) + "fF len=" + TextUtils.formatDouble(sqrs, 2) + "\n");
                					tLineCount++;
                					n0=n1;
                				}
                        		sqrs = 0;
                        		res = 0.0;
                        		cap = 0;
                        		sqrs += length / width;
                    	   		res += segmentedNets.getRes(CurrAi).doubleValue();
                    	   		cap += segmentedNets.getArcCap(CurrAi);
                			}
                			
                			// Decide which port of the current arc to use to continue traversing the network
                			if (MainPI == CurrAi.getHeadPortInst()) {
                				MainAi = CurrAi;
                				MainPI = MainAi.getTailPortInst(); 
                				ConIT = MainAi.getTailPortInst().getConnections();
                				n1 = segmentedNets.getNetName(MainAi.getTailPortInst());
                			} else {
                				MainAi = CurrAi;
                				MainPI = MainAi.getHeadPortInst(); 
                				ConIT = MainAi.getHeadPortInst().getConnections();
                				n1 = segmentedNets.getNetName(MainAi.getHeadPortInst());
                			}
                		}
                		
                		// Once, one end of the network is reached, start traversing from the 
                		// head port instance of the first arc in the other direction now.
                		if (!ConIT.hasNext() && !startAgain)
        				{
        					ConIT = FirstAi.getHeadPortInst().getConnections();
        					MainPI = FirstAi.getHeadPortInst();
        					startAgain = true;
        					
        					if(sqrs > 3) {
        						out.multiLinePrint(false, "XP" + tLineCount + " " + n0 + " " + n1 +" RCLINE R=" + TextUtils.formatDouble(res/sqrs, 2) + " C=" + TextUtils.formatDouble(cap/sqrs, 2) + "fF len=" + TextUtils.formatDouble(sqrs, 2) + "\n");
        						tLineCount++;
        					}
        					preLayer = "";
        					sqrs = 0;
                    		res = 0.0;
                    		cap = 0;
                    		n0=segmentedNets.getNetName(FirstAi.getHeadPortInst());
        				}
                	}	
                   	if(sqrs > 3 && res > 0 && cap >0 ) {
                   		out.multiLinePrint(false, "XP" + tLineCount + " " + n0 + " " + n1 +" RCLINE R=" + TextUtils.formatDouble(res/sqrs, 2) + " C=" + TextUtils.formatDouble(cap/sqrs, 2) + "fF len=" + TextUtils.formatDouble(sqrs, 2) + "\n");
                   	    tLineCount++;
                   	}
                }
			}
        }

		// Print the subckt Spice code
        if (!alreadyPrinted){
        	out.multiLinePrint(false, ".subckt RCLINE n1 n2 \n");
        	out.multiLinePrint(false, "o1 n1 0 n2 0 TRC \n");
        	out.multiLinePrint(false, ".model TRC ltra R={R} C={C} len={len} \n");
        	out.multiLinePrint(false, ".ends RCLINE \n");
        	alreadyPrinted = true;
        }
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -