?? sim.java
字號:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: Sim.java * Asynchronous Logic Simulator engine * 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.text.TextUtils;import com.sun.electric.tool.simulation.DigitalSignal;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.simulation.als.ALS.Load;import com.sun.electric.tool.simulation.als.ALS.Stat;import com.sun.electric.tool.user.waveform.Panel;import java.awt.geom.Rectangle2D;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;/** * Class to do the engine of the ALS Simulator. */public class Sim{ private ALS als; private List<Load> chekList = new ArrayList<Load>();// private Load chekRoot; private HashMap<ALS.Node,List<ALS.Trak>> tracking; private static String [] stateDesc = {"High", "Undefined", "Low"}; private static String [] strengthDesc = {"Off-", "Weak-", "Weak-", "", "", "Strong-", "Strong-"}; boolean tracing = false; Sim(ALS als) { this.als = als; } /** * Method to initialize the simulator for a simulation run. The * vector link list is copied to a master event scheduling link list and * the database is initialized to its starting values. After these housekeeping * tasks are completed the simulator is ready to start the actual simulation. * Returns the time where the simulation quiesces. */ double initializeSimulator(boolean force) { als.timeAbs = 0.0; tracking = new HashMap<ALS.Node,List<ALS.Trak>>(); while (als.linkFront != null) { if (als.linkFront.down != null) { als.linkFront.down.right = als.linkFront.right; als.linkFront = als.linkFront.down; } else { als.linkFront = als.linkFront.right; } } als.linkBack = null; for (ALS.Link linkHead = als.setRoot; linkHead != null; linkHead = linkHead.right) { ALS.Link linkPtr2 = new ALS.Link(); if (linkPtr2 == null) return(als.timeAbs); linkPtr2.type = linkHead.type; linkPtr2.ptr = linkHead.ptr; linkPtr2.state = linkHead.state; linkPtr2.strength = linkHead.strength; linkPtr2.priority = linkHead.priority; linkPtr2.time = linkHead.time; linkPtr2.primHead = null; insertLinkList(linkPtr2); } for(ALS.Node nodeHead : als.nodeList) { nodeHead.sumState = Stimuli.LOGIC_LOW; nodeHead.sumStrength = Stimuli.OFF_STRENGTH; nodeHead.newState = new Integer(Stimuli.LOGIC_LOW); nodeHead.newStrength = Stimuli.OFF_STRENGTH; nodeHead.arrive = 0; nodeHead.depart = 0; nodeHead.tLast = 0.0; for(Stat statHead : nodeHead.statList) { statHead.newState = Stimuli.LOGIC_LOW; statHead.newStrength = Stimuli.OFF_STRENGTH; statHead.schedOp = 0; } } // now run the simulation boolean update = Simulation.isBuiltInResimulateEach(); if (force) update = true; if (update) { // fire events until end of time or quiesced System.out.print("Simulating..."); // determine highest time to simulate Rectangle2D bounds = als.an.getBounds(); double tMax = bounds.getMaxX(); for(Iterator<Panel> it = als.ww.getPanels(); it.hasNext(); ) { Panel wp = it.next(); double panelMax = wp.getMaxXAxis(); if (panelMax > tMax) tMax = panelMax; } while (als.linkFront != null && als.linkFront.time <= tMax) { if (fireEvent()) break; if (chekList.size() != 0) { if (scheduleNewEvents()) break; } } // redisplay results fillDisplayArrays(); System.out.println("Done. Ran to time " + TextUtils.convertToEngineeringNotation(als.timeAbs)); } return als.timeAbs; } /** * Method to extract the ALS simulation data and update the Stimuli database */ private void fillDisplayArrays() { HashSet<DigitalSignal> sigsChanged = new HashSet<DigitalSignal>(); for(ALS.Node node : tracking.keySet()) { DigitalSignal sig = node.sig; List<ALS.Trak> trakHeads = tracking.get(node); int count = trakHeads.size(); double [] timeVector = new double[count+1]; int [] stateVector = new int[count+1]; timeVector[0] = 0; stateVector[0] = Stimuli.LOGIC_LOW | Stimuli.OFF_STRENGTH; int j=1; for(ALS.Trak trakHead : trakHeads) { timeVector[j] = trakHead.time; stateVector[j] = trakHead.state; j++; } sig.setTimeVector(timeVector); sig.setStateVector(stateVector); sigsChanged.add(sig); } // set all other signals to "empty" int [] stateVector = new int[1]; stateVector[0] = 0; double [] timeVector = new double[1]; timeVector[0] = 0; for(Signal s : als.an.getSignals()) { DigitalSignal sig = (DigitalSignal)s; if (sigsChanged.contains(sig)) continue; sig.setTimeVector(timeVector); sig.setStateVector(stateVector); } als.ww.repaint(); } /** * Method to get the entry from the front of the event scheduling * link list and updates the database accordingly. If a node is updated by a * user defined vector the node value is changed as specified in the linklist * entry. If a transition fired, all the output nodes are updated as specified * in the truth table for the transtion. Returns true on error. */ private boolean fireEvent() { als.timeAbs = als.linkFront.time; ALS.Link linkHead = als.linkFront; if (als.linkFront.down != null) { als.linkFront = als.linkFront.down; als.linkFront.left = null; als.linkFront.right = linkHead.right; als.linkFront.up = linkHead.up; if (als.linkFront.right != null) { als.linkFront.right.left = als.linkFront; } else { als.linkBack = als.linkFront; } } else { als.linkFront = als.linkFront.right; if (als.linkFront != null) { als.linkFront.left = null; } else { als.linkBack = null; } } tracing = false; switch (linkHead.type) { case 'G': ALS.Stat statHead = (ALS.Stat)linkHead.ptr; if (statHead.nodePtr.traceNode) { String s2 = als.computeNodeName(statHead.nodePtr); System.out.println(TextUtils.convertToEngineeringNotation(als.timeAbs) + ": Firing gate " + statHead.primPtr.name + statHead.primPtr.level + ", net " + s2); tracing = true; } if (statHead.schedState != linkHead.state || statHead.schedOp != linkHead.operatr || statHead.schedStrength != linkHead.strength) { break; } statHead.schedOp = 0; char operatr = linkHead.operatr; int operand = 0; if (operatr < 128) { operand = ((Integer)linkHead.state).intValue(); } else { operatr -= 128;// ALS.Node nodeHead = (ALS.Node)linkHead.state;// operand = nodeHead.sumState; } int state = 0; switch (operatr) { case '=': state = operand; break; case '+': state = statHead.nodePtr.sumState + operand; break; case '-': state = statHead.nodePtr.sumState - operand; break; case '*': state = statHead.nodePtr.sumState * operand; break; case '/': state = statHead.nodePtr.sumState / operand; break; case '%': state = statHead.nodePtr.sumState % operand; break; default: System.out.println("Invalid arithmetic operator: " + operatr); return true; } if (state == statHead.newState && linkHead.strength == statHead.newStrength) { break; } statHead.newState = state; statHead.newStrength = linkHead.strength; createCheckList(statHead.nodePtr, linkHead); break; case 'N': ALS.Node nodeHead = (ALS.Node)linkHead.ptr; if (nodeHead.traceNode) { String s2 = als.computeNodeName(nodeHead); System.out.println(TextUtils.convertToEngineeringNotation(als.timeAbs) + ": Changed state of net " + s2); tracing = true; } if (linkHead.state == nodeHead.newState && linkHead.strength == nodeHead.newStrength) break; nodeHead.newState = linkHead.state; nodeHead.newStrength = linkHead.strength; createCheckList(nodeHead, linkHead); break; case 'C': double time = als.timeAbs; ALS.Row rowHead = (ALS.Row)linkHead.ptr; for(Object obj : rowHead.inList) { ALS.Link vectHead = (ALS.Link)obj; ALS.Link linkPtr2 = new ALS.Link(); linkPtr2.type = 'N'; linkPtr2.ptr = vectHead.ptr; linkPtr2.state = vectHead.state; linkPtr2.strength = vectHead.strength; linkPtr2.priority = vectHead.priority; linkPtr2.time = time; linkPtr2.primHead = null; insertLinkList(linkPtr2); time += vectHead.time; } if (((Integer)linkHead.state).intValue() == 0) { calculateClockTime(linkHead, rowHead); return false; } linkHead.state = new Integer(((Integer)linkHead.state).intValue() - 1); if (((Integer)linkHead.state).intValue() != 0) { calculateClockTime(linkHead, rowHead); return false; } } return false; } /** * Method to calculate the sum state and strength for a node and if * it has changed from a previous check it will enter the input transition list * into a master check list that is used by the event scheduling routine. * It should be noted that it is neccessary to calculate the sum strength and * state for a node because it is possible to have nodes that have more than * one transition driving it. */ private void createCheckList(ALS.Node nodeHead, ALS.Link linkHead) { // get initial state of the node int state = ((Integer)nodeHead.newState).intValue();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -