📄 als.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: ALS.java * Asynchronous Logic Simulator main module * Original C Code written by Brent Serbin and Peter J. Gallant * Translated to Java by Steven M. Rubin, Sun Microsystems. * * Copyright (c) 2005 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.simulation.als;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.text.TextUtils;import com.sun.electric.tool.Job;import com.sun.electric.tool.io.FileType;import com.sun.electric.tool.simulation.DigitalAnalysis;import com.sun.electric.tool.simulation.DigitalSignal;import com.sun.electric.tool.simulation.Engine;import com.sun.electric.tool.simulation.Signal;import com.sun.electric.tool.simulation.Simulation;import com.sun.electric.tool.simulation.Stimuli;import com.sun.electric.tool.user.dialogs.OpenFile;import com.sun.electric.tool.user.waveform.Panel;import com.sun.electric.tool.user.waveform.WaveSignal;import com.sun.electric.tool.user.waveform.WaveformWindow;import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.LineNumberReader;import java.io.PrintWriter;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;/** * Class to control the ALS Simulator. */public class ALS extends Engine{ /** initial size of simulation window */ private static final double DEFTIMERANGE = 0.0000002; /** the simulation engine */ Sim theSim; /** the circuit flattener */ Flat theFlat; /** the waveform window showing this simulator */ WaveformWindow ww; /** the stimuli set currently being displayed */ DigitalAnalysis an; /** current time in the simulator */ double timeAbs; /** saved list of stimuli when refreshing */ List<String> stimuliList; List<Model> modelList; List<Model> primList = new ArrayList<Model>(); IO ioPtr2; Connect cellRoot = null; ALSExport exPtr2; List<Node> nodeList = new ArrayList<Node>(); Node driveNode; Link linkFront = null; Link linkBack = null; Link setRoot = null; List ioPtr1; char [] instBuf = null; int [] instPtr = null; private int iPtr; private String delay; private Model modPtr2; private String [] netlistStrings; private int netlistStringPoint; private int iBufSize; private int iPtrSize; private double deltaDef; private double linearDef; private double expDef; private double randomDef; private double absDef;// /**// * DelayTypes is a typesafe enum class that describes types of delay.// */// private static class DelayTypes// {// private DelayTypes() {}//// /**// * Returns a printable version of this DelayTypes.// * @return a printable version of this DelayTypes.// */// public String toString() { return ""; }//// /** Describes a minimum delay. */ public static final DelayTypes DELAY_MIN = new DelayTypes();// /** Describes a typical delay. */ public static final DelayTypes DELAY_TYP = new DelayTypes();// /** Describes a maximum delay. */ public static final DelayTypes DELAY_MAX = new DelayTypes();// } static class Model { String name; char type; Object ptr; /* may be Connect, Row, or Func */ List<ALSExport> exList; List<IO> setList; List<Load> loadList; char fanOut; int priority; String level; /* hierarchical level */ Model(String name, char type) { this.name = name; this.type = type; ptr = null; exList = new ArrayList<ALSExport>(); setList = new ArrayList<IO>(); loadList = new ArrayList<Load>(); fanOut = 0; priority = 1; } }; static class Row { List<Object> inList; List<Object> outList; double delta; double linear; double exp; double random; double abs; /* BA delay - SDF absolute port delay */ Row next; String delay; /* delay transition name (01, 10, etc) */ }; static class IO { Object nodePtr; char operatr; Object operand; int strength; }; static class Connect { String instName; String modelName; List<ALSExport> exList; Connect parent; Connect child; Connect next; }; static class ALSExport { Object nodeName; Node nodePtr; }; static class Load { Object ptr; double load; }; static class Node { Connect cellPtr; DigitalSignal sig; private int num; int sumState; int sumStrength; Object newState; int newStrength; boolean traceNode; List<Stat> statList; List<Load> pinList; double load; int visit; int arrive; int depart; double tLast; private static int nSeq = 1; Node() { num = nSeq++; } int getIndex() { return num; } }; static class Stat { Model primPtr; Node nodePtr; int newState; int newStrength; char schedOp; Object schedState; int schedStrength; }; static class Link { Link left; Link right; Link up; Link down; Object ptr; char type; char operatr; Object state; int strength; int priority; double time; Model primHead; }; static class Trak { int state; double time; }; static class Func { UserProc procPtr; List<ALSExport> inList; double delta; double linear; double exp; double abs; /* absolute delay for back annotation */ double random; Object userPtr; }; static class UserProc { protected ALS als; private static HashMap<String,UserProc> funcMap = new HashMap<String,UserProc>(); void nameMe(ALS als, String name) { this.als = als; funcMap.put(name.toUpperCase(), this); } void simulate(Model primHead) {} /** * Method to return the address of the function specified by * the calling argument character string. Each time a routine is added to the * user library of event driven "C" functions an entry must be made into this * procedure to include it in the known list of user routines. It is highly * recommended that all user defined procedures be named with capital letters. * This is done for two reasons: 1) the text in the netlist is converted to * upper case by the parser and this means caps must be used in the string * compare statements below, and 2) the user defined function routines will * be easily identifiable in source code listings. Returns zero on error. * * Calling Arguments: * s1 = pointer to character string containing the name of the user * defined function */ static UserProc getFunctionAddress(String s1) { UserProc ret = funcMap.get(s1); if (ret == null) System.out.println("ERROR: Unable to find user function " + s1 + " in library"); return ret; } /** * Method to insert a node updating task into the * time scheduling link list. The user must specify the node address, signal * state, signal strength, and update time in the calling arguments. If the * user updates the value of a node manually without calling this procedure, * the event driving algorithm will not be able to detect this change. This means * that the effects of the node update will not be propagated throughout the * simulation circuit automatically. By scheduling the event through the master * link list, this problem can be avoided. Returns true on error. * * Calling Arguments: * nodeHead = pointer to the node data structure to be updated * operatr = char indicating operation to be performed on node * state = integer value representing the state of the node * strength = integer value representing the logic stregth of the signal * time = double value representing the time the change is to take place */ protected void scheduleNodeUpdate(Model primHead, ALSExport exHead, int operatr, Object state, int strength, double time) { Stat statHead = (Stat)exHead.nodeName; if (statHead.schedOp == operatr && statHead.schedState == state && statHead.schedStrength == strength) { return; } if (als.getSim().tracing) { String s2 = als.computeNodeName(statHead.nodePtr); System.out.println(" Schedule(F) gate " + statHead.primPtr.name + statHead.primPtr.level + ", net " + s2 + " at " + TextUtils.convertToEngineeringNotation(time)); } Link linkPtr2 = new Link(); linkPtr2.type = 'G'; linkPtr2.ptr = statHead; linkPtr2.operatr = statHead.schedOp = (char)operatr; linkPtr2.state = statHead.schedState = state; linkPtr2.strength = statHead.schedStrength = strength; linkPtr2.priority = 1; linkPtr2.time = time; linkPtr2.primHead = primHead; als.getSim().insertLinkList(linkPtr2); } /** * Method to examine all the elements feeding into a node that is * connected to the current bidirectional element and insures that there are no * bidirectional "loops" found in the network paths. If a loop is found the * effects of the element are ignored from the node summing calculation. * * Calling Arguments: * primHead = pointer to current bidirectional element * side[] = pointers to nodes on each side of the bidir element * outStrength = output strength */ private Node targetNode; private int biDirClock = 0; protected void calculateBidirOutputs(Model primHead, ALSExport [] side, int outStrength) { for(int i=0; i<2; i++) { ALSExport thisSide = side[i]; ALSExport otherSide = side[(i+1)%2]; Node sumNode = thisSide.nodePtr; targetNode = otherSide.nodePtr; if (targetNode == als.driveNode) continue; int state = ((Integer)sumNode.newState).intValue(); int strength = sumNode.newStrength; biDirClock++; for(Stat statHead : sumNode.statList) { if (statHead.primPtr == primHead) continue; sumNode.visit = biDirClock; int thisStrength = statHead.newStrength; int thisState = statHead.newState; if (thisStrength > strength) { state = thisState; strength = thisStrength; continue; } if (thisStrength == strength) { if (thisState != state) state = Stimuli.LOGIC_X; } } // make strength no more than maximum output strength if (strength > outStrength) strength = outStrength; Func funcHead = (Func)primHead.ptr; double time = als.timeAbs + (funcHead.delta * targetNode.load); scheduleNodeUpdate(primHead, otherSide, '=', new Integer(state), strength, time); } } } ALS() { theSim = new Sim(this); theFlat = new Flat(this); } Sim getSim() { return theSim; } /** * Method to simulate the a Cell, given its context and the Cell with the real netlist. * @param netlistCell the Cell with the real ALS netlist. * @param cell the original Cell being simulated. */ public static void simulateNetlist(Cell netlistCell, Cell cell) { ALS theALS = new ALS(); theALS.doSimulation(netlistCell, cell, null, null); } /** * Method to restart a simulation and reload the circuit. * @param netlistCell the cell with the netlist. * @param cell the cell being simulated. * @param prevALS the simulation that is being reloaded. */ public static void restartSimulation(Cell netlistCell, Cell cell, ALS prevALS) { WaveformWindow ww = prevALS.ww; List<String> stimuliList = prevALS.stimuliList; ALS theALS = new ALS(); theALS.doSimulation(netlistCell, cell, ww, stimuliList); } /** * Method to reload the circuit data. */ public void refresh() { // save existing stimuli in this simulator object stimuliList = getStimuliToSave(); // restart everything Simulation.startSimulation(Simulation.ALS_ENGINE, false, an.getStimuli().getCell(), this); } /** * Method to update the simulation (because some stimuli have changed). */ public void update() { theSim.initializeSimulator(true); } /** * Method to set the currently-selected signal high at the current time. */ public void setSignalHigh() { makeThemThus(Stimuli.LOGIC_HIGH); } /** * Method to set the currently-selected signal low at the current time. */ public void setSignalLow() { makeThemThus(Stimuli.LOGIC_LOW); } /** * Method to set the currently-selected signal to have a clock with a given period. */ public void setClock(double period) { List<Signal> signals = ww.getHighlightedNetworkNames(); if (signals.size() == 0) { Job.getUserInterface().showErrorMessage("Must select a signal before setting a Clock on it", "No Signals Selected"); return; } for(Signal sig : signals) { String sigName = sig.getFullName(); Node nodeHead = findNode(sigName); if (nodeHead == null) { System.out.println("ERROR: Unable to find node " + sigName); continue; } double time = ww.getMainXPositionCursor(); Link vectPtr2 = new Link(); vectPtr2.type = 'N'; vectPtr2.ptr = nodeHead; vectPtr2.state = new Integer(Stimuli.LOGIC_HIGH); vectPtr2.strength = Stimuli.VDD_STRENGTH; vectPtr2.priority = 1; vectPtr2.time = time; vectPtr2.right = null; Link vectPtr1 = new Link(); vectPtr1.type = 'N'; vectPtr1.ptr = nodeHead; vectPtr1.state = new Integer(Stimuli.LOGIC_LOW); vectPtr1.strength = Stimuli.VDD_STRENGTH; vectPtr1.priority = 1; vectPtr1.time = period / 2.0; vectPtr1.right = vectPtr2; Row clokHead = new Row(); clokHead.inList = new ArrayList<Object>(); clokHead.inList.add(vectPtr1); clokHead.inList.add(vectPtr2); clokHead.outList = new ArrayList<Object>(); clokHead.delta = period; clokHead.linear = 0; clokHead.exp = 0; clokHead.abs = 0; clokHead.random = 0; clokHead.next = null; clokHead.delay = null; Link setHead = new Link(); setHead.type = 'C'; setHead.ptr = clokHead; setHead.state = new Integer(0); setHead.priority = 1; setHead.time = time; setHead.right = null; insertSetList(setHead); } theSim.initializeSimulator(true); } /** * Method to set the currently-selected signal undefined at the current time. */ public void setSignalX() { makeThemThus(Stimuli.LOGIC_X); } /** * Method to show information about the currently-selected signal. */ public void showSignalInfo() { List<Signal> signals = ww.getHighlightedNetworkNames(); if (signals.size() == 0) { Job.getUserInterface().showErrorMessage("Must select a signal before displaying it", "No Signals Selected"); return; } for(Signal sig : signals) { Node nodeHead = findNode(sig.getFullName()); if (nodeHead == null) { System.out.println("ERROR: Unable to find node " + sig.getFullName()); continue; } String s1 = Stimuli.describeLevel(((Integer)nodeHead.newState).intValue()); System.out.println("Node " + sig.getFullName() + ": State = " + s1 +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -