/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: DigitalSignal.java * * Copyright (c) 2004 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; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.List; /** * Class to define a digital signal in the simulation waveform window. */ public class DigitalSignal extends Signal { /** the DigitalAnalysis object in which this DigitalSignal resides. */ private DigitalAnalysis an; /** a list of signals on this bussed signal */ private List<DigitalSignal> bussedSignals; /** the number of busses that reference this signal */ private int busCount; /** an array of time values on this signal (null to use common time) */ private double [] time; private int [] state; /** * Constructor for a digital signal. * @param an the DigitalAnalysis object in which this signal will reside. */ public DigitalSignal(DigitalAnalysis an) { this.an = an; an.addSignal(this); } @Override public void finished() { super.finished(); if (bussedSignals != null) { for (Signal s : bussedSignals) s.finished(); bussedSignals.clear(); } busCount = 0; time = null; state = null; } /** * Method to return the DigitalAnalysis in which this signal resides. * @return the DigitalAnalysis in which this signal resides. */ @Override public DigitalAnalysis getAnalysis() { return an; } /** * Method to request that this signal be a bus. * Builds the necessary data structures to hold bus information. */ public void buildBussedSignalList() { bussedSignals = new ArrayList<DigitalSignal>(); an.getBussedSignals().add(this); } /** * Method to return a List of signals on this bus signal. * Each entry in the List points to another simulation signal that is on this bus. * @return a List of signals on this bus signal. */ public List<DigitalSignal> getBussedSignals() { return bussedSignals; } /** * Method to request that this bussed signal be cleared of all signals on it. */ public void clearBussedSignalList() { for(DigitalSignal sig : bussedSignals) sig.busCount--; bussedSignals.clear(); } /** * Method to add a signal to this bus signal. * @param ws a single-wire signal to be added to this bus signal. */ public void addToBussedSignalList(DigitalSignal ws) { bussedSignals.add(ws); ws.busCount++; } /** * Method to tell whether this signal is part of a bus. * @return true if this signal is part of a bus. */ public boolean isInBus() { return busCount != 0; } // time /** * Method to build a time vector for this TimedSignal. * TimedSignals can have their own time information, or they can use a "common time" array * that is part of the simulation data. * If using common time, then each TimedSignal must have the same number of entries, and * each entry must be at the same time as the corresponding entries in other TimedSignals. * Using common time saves memory, because the time information does not have to be * stored with each TimedSignal. * This method requests that the TimedSignal have its own time array, and not use common time data. * @param numEvents the number of events on this TimedSignal (the length of the time array). */ public void buildTime(int numEvents) { time = new double[numEvents]; } /** * Method to return the value of time for a given event on this TimedSignal. * Depending on whether common time data is being used, the time information is * found on this TimedSignal or on the overall simulation data. * @param index the event being querried (0-based). * @return the value of time at that event. */ public double getTime(int index) { return time[index]; } /** * Method to return the time vector for this TimedSignal. * The vector is only valid if this TimedSignal is NOT using common time. * TimedSignals can have their own time information, or they can use a "common time" array * that is part of the simulation data. * If using common time, then each TimedSignal must have the same number of entries, and * each entry must be at the same time as the corresponding entries in other TimedSignals. * @return the time array for this TimedSignal. * Returns null if this TimedSignal uses common time. */ public double [] getTimeVector() { return time; } /** * Method to set the time vector for this TimedSignal. * Overrides any previous time vector that may be on this TimedSignal. * TimedSignals can have their own time information, or they can use a "common time" array * that is part of the simulation data. * If using common time, then each TimedSignal must have the same number of entries, and * each entry must be at the same time as the corresponding entries in other TimedSignals. * @param time a new time vector for this TimedSignal. */ public void setTimeVector(double [] time) { bounds = null; this.time = time; } /** * Method to set an individual time entry for this TimedSignal. * Only applies if common time is NOT being used for this TimedSignal. * TimedSignals can have their own time information, or they can use a "common time" array * that is part of the simulation data. * If using common time, then each TimedSignal must have the same number of entries, and * each entry must be at the same time as the corresponding entries in other TimedSignals. * @param entry the entry in the event array of this TimedSignal (0-based). * @param t the new value of time at this event. */ public void setTime(int entry, double t) { bounds = null; time[entry] = t; } // state values /** * Method to initialize this simulation signal with a specified number of events. * Allocates an array to hold those events. * @param numEvents the number of events in this signal. */ public void buildState(int numEvents) { state = new int[numEvents]; } /** * Method to set the state of this signal at a given event. * @param index the event index (0-based). * @param st the state of the signal at that event. */ public void setState(int index, int st) { state[index] = st; bounds = null; } /** * Method to get the state of this signal at a given event. * @param index the event index (0-based). * @return the state of the signal at that event. */ public int getState(int index) { return state[index]; } /** * Method to return the state information for all events in this signal. * @return the state array for this signal. */ public int [] getStateVector() { return state; } /** * Method to set the state information for all events in this signal. * @param state an array of state information for every event on this signal. */ public void setStateVector(int [] state) { this.state = state; bounds = null; } /** * Method to return the number of events in this signal. * This is the number of events along the horizontal axis, usually "time". * @return the number of events in this signal. */ public int getNumEvents() { if (state == null) return 0; return state.length; } /** * Method to compute the low and high range of time value on this signal. * The result is stored in the "bounds", "leftEdge", and "rightEdge" field variables. */ protected void calcBounds() { boolean first = true; double lowTime = 0, highTime = 0; if (state != null) { for(int i=0; i<state.length; i++) { double time = getTime(i); if (i == 0) leftEdge = time; else if (i == state.length-1) rightEdge = time; if (first) { first = false; lowTime = highTime = time; } else { if (time < lowTime) lowTime = time; if (time > highTime) highTime = time; } } } bounds = new Rectangle2D.Double(lowTime, 0, highTime-lowTime, 1); } }