/* -*- tab-width: 4 -*-
*
* Electric(tm) VLSI Design System
*
* File: Arc.java
* Written by Jonathan Gainsley, Sun Microsystems.
*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
*
* 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.sctiming;
import java.util.List;
import java.util.ArrayList;
/**
* A Timing Arc. Can be combinational or sequential.
* A Timing arc consists of a single input, a single output,
* zero or more stable (non-changing) inputs, and zero
* or more initial condition for internal nodes. Node and
* pin names should correspond to the top cell (device to be
* characterized). For sequential timing, a clk (and optionally
* a clkFalse) are also specified.
*/
public class Arc {
List<PinEdge> stableInputs = new ArrayList<PinEdge>();
PinEdge input;
PinEdge output;
TableData data; // simulation measurement results
Table2D data2d_inbuf_outload;
Table2D data2d_clkbuf_outload;
Table2D data2d_inbuf_clkbuf;
PinEdge clk = null;
PinEdge clkFalse = null;
List<PinEdge> initialConditions = new ArrayList<PinEdge>();
String outputLoadSweep = null;
String inputBufferSweep = null;
List<String> unusedOutputs = new ArrayList<String>();
List<PinEdge> dependentStableInputs = new ArrayList<PinEdge>();
PinEdge glitchNode = null;
/**
* Set the transition on the input being stimulated
* @param pin input pin name
* @param transition transition type
*/
public void setInputTransition(String pin, PinEdge.Transition transition) {
if (input != null) {
System.out.println("Warning: specified singular input pin twice, ignoring second assingment");
return;
}
input = new PinEdge(pin, transition);
}
/**
* Set the expected transition on the output
* @param pin output pin name
* @param transition transition type
*/
public void setOutputTransition(String pin, PinEdge.Transition transition) {
if (output != null) {
System.out.println("Warning: specified singular output pin twice, ignoring second assingment");
return;
}
output = new PinEdge(pin, transition);
}
/**
* Add a stable signal to an unused input pin
* @param pin input pin name
* @param transition stable transition type
*/
public void addStableInput(String pin, PinEdge.Transition transition) {
stableInputs.add(new PinEdge(pin, transition));
}
/**
* Add a stable signal to a dependent input pin - the state of the
* input pin affects the type (rise/fall) of transition on the output.
* This is used for example in an XOR gate, where an input rising edge
* can cause both a rising and falling output edge, dependent on the
* state of the other input.
* @param pin input pin name
* @param transition stable transition type
*/
public void addDependentStableInput(String pin, PinEdge.Transition transition) {
stableInputs.add(new PinEdge(pin, transition));
dependentStableInputs.add(new PinEdge(pin, transition));
}
/**
* Add a stable signal (voltage level) to an unused input pin
* @param pin input pin name
* @param voltage voltage value
*/
public void addStableInput(String pin, double voltage) {
stableInputs.add(new PinEdge(pin, voltage));
}
/**
* Set the clock transition for a sequential cell
* @param pin clock input pin
* @param transition transition type
*/
public void setClkTransition(String pin, PinEdge.Transition transition) {
if (clk != null) {
System.out.println("Warning: specified singular clk pin twice, ignoring second assingment");
return;
}
clk = new PinEdge(pin, transition);
}
/**
* If a clock-bar pin exists, set the transition for it. It
* will occur at the same time as the clock transition
* @param pin the clock-bar pin
* @param transition transition type
*/
public void setClkFalseTransition(String pin, PinEdge.Transition transition) {
if (clkFalse != null) {
System.out.println("Warning: specified singular clkFalse pin twice, ignoring second assingment");
return;
}
clkFalse = new PinEdge(pin, transition);
}
/**
* Add an initial condition on a node inside the device under test
* @param node the internal node name
* @param value voltage value of the initial condition
*/
public void addDUTInitialCondition(String node, double value) {
initialConditions.add(new PinEdge(node, value));
}
/**
* Specify an intial condition on a node inside the device under test,
* to be used during glitch-based Hold time tests.
* The transition sets the glitch transition type. (Rising glitch or falling glitch)
* @param node the internal node name
* @param transition transition type
*/
public void setHoldTimeGlitchNode(String node, PinEdge.Transition transition) {
if (glitchNode != null) {
System.out.println("Warning: specified singular glitch node twice, ignoring second assingment");
return;
}
glitchNode = new PinEdge(node, transition);
}
/**
* Specify an unused output pin. This pin will be ignored for characterization
* of this arc.
* @param pin the output pin
*/
public void addUnusedOutput(String pin) {
if (unusedOutputs.contains(pin)) return;
unusedOutputs.add(pin);
}
public String toString() {
StringBuffer desc = new StringBuffer();
for (PinEdge in : stableInputs) {
appendDesc(desc, in);
}
appendDesc(desc, input);
if (clk != null) {
appendDesc(desc, clk);
}
desc.append(output.pin); desc.append("_");
desc.append(descTran(output.transition));
return desc.toString();
}
private void appendDesc(StringBuffer buf, PinEdge pin) {
buf.append(pin.pin); buf.append("_");
buf.append(descTran(pin.transition)); buf.append("_");
}
/**
* Get a single character description of the transition type
* @param tran the transition type
* @return a single character description
*/
public static String descTran(PinEdge.Transition tran) {
switch(tran) {
case STABLE0: return "0";
case STABLE1: return "1";
case RISE: return "R";
case FALL: return "F";
case STABLEV: return "V";
}
return "";
}
/**
* Set the sweep values (in X drive strength). The number
* of values must be equal to the number of values specified in the
* default settings
* @param sweep space delimited list of values
*/
public void setOutputLoadSweep(String sweep) {
this.outputLoadSweep = sweep;
}
public String getOutputLoadSweep() { return outputLoadSweep; }
/**
* Set the sweep values (in X drive strength) for the input buffer.
* @param sweep space delimited list of values
*/
public void setInputBufferSweep(String sweep) {
this.inputBufferSweep = sweep;
}
public String getInputBufferSweep() { return inputBufferSweep; }
}