All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.electric.tool.simulation.DigitalSample Maven / Gradle / Ivy

There is a newer version: 9.02-e
Show newest version
/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: Signal.java
 *
 * 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;

import com.sun.electric.database.geometry.PolyBase;
import com.sun.electric.database.geometry.btree.unboxed.LatticeOperation;
import com.sun.electric.database.geometry.btree.unboxed.Unboxed;
import com.sun.electric.tool.user.waveform.Panel;
import com.sun.electric.tool.user.waveform.Panel.WaveSelection;
import com.sun.electric.tool.user.waveform.WaveSignal;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.geom.Rectangle2D;
import java.util.List;

/**
 *  An implementation of Sample for digital data; supports HIGH/LOW
 *  (at the IEEE-standard drive strengths) as well as X and Z (at only
 *  a single drive strength).
 *
 *  Instances of DigitalSample are interned for efficiency; there is
 *  only ever one instance of DigitalSample with any given
 *  value/strength, so == can be used for equality tests.
 */
public class DigitalSample implements Sample
{
    // no need for more than one instance of each...
    public static final DigitalSample LOGIC_0;
    public static final DigitalSample LOGIC_1;
    public static final DigitalSample LOGIC_X;
    public static final DigitalSample LOGIC_Z;

    private static DigitalSample[][] cache;

    static
    {
        cache = new DigitalSample[4][];
        for(int i=0; i<4; i++) cache[i] = new DigitalSample[8];
        for(Value value : Value.values())
            for(Strength strength : Strength.values())
                if (!((value == Value.Z) ^ (strength == Strength.HIGH_IMPEDANCE)))
                    cache[value.v+1][strength.v] = new DigitalSample(value, strength);
        LOGIC_0 = getSample(Value.LOW,  Strength.STRONG_PULL);
        LOGIC_1 = getSample(Value.HIGH, Strength.STRONG_PULL);
        LOGIC_X = getSample(Value.X,    Strength.STRONG_PULL);
        LOGIC_Z = getSample(Value.Z,    Strength.HIGH_IMPEDANCE);
    }

    public static DigitalSample getSample(Value value, Strength strength)
    {
        if ((value == Value.Z) ^ (strength == Strength.HIGH_IMPEDANCE))
            throw new RuntimeException("Logic=Z and Strength=HIGH_IMPEDANCE may only be used together");
        return cache[value.v+1][strength.v];
    }

    private Value value;
    private Strength strength;

    private DigitalSample(Value value, Strength strength)
    {
        if ((value == Value.Z) ^ (strength == Strength.HIGH_IMPEDANCE))
            throw new RuntimeException("Logic=Z and Strength=HIGH_IMPEDANCE may only be used together");
        this.value = value;
        this.strength = strength;
    }

    /** 
     *  Possible signal values.
     */
    public static enum Value
    {
        HIGH(1),
        X(0),
        LOW(-1),
        Z(-1);
        private final int v;
        private Value(int v) { this.v = v; }
    }

    /** 
     *  These are the strength levels from the IEEE Verilog standard;
     *  they weren't just arbitrarily made up; sort order is
     *  weak-to-strong.
     */
    public static enum Strength
    {
        SUPPLY_DRIVE(7),
        STRONG_PULL(6),         // IEEE standard says "STRONG_PULL" is the default
        PULL_DRIVE(5),
        LARGE_CAPACITANCE(4),
        WEAK_DRIVE(3),
        MEDIUM_CAPACITANCE(2),
        SMALL_CAPACITANCE(1),
        HIGH_IMPEDANCE(0);      // valid only for LOGIC_Z
        private final int v;
        private Strength(int v) { this.v = v; }
    };

    public boolean equals(Object o) { return this == o; }

    public int hashCode() { return getByteRepresentation() & 0xff; }

    public Sample lub(Sample s)
    {
        if (!(s instanceof DigitalSample)) throw new RuntimeException("tried to call DigitalSample.lub("+s.getClass().getName()+")");
        DigitalSample ds = (DigitalSample)s;
        if (ds.value.v >= value.v && ds.strength.v >= strength.v) return ds;
        if (ds.value.v <= value.v && ds.strength.v <= strength.v) return this;
        return cache[Math.max(ds.value.v, value.v)+1][Math.max(ds.strength.v, strength.v)+1];
    }

    public Sample glb(Sample s)
    {
        if (!(s instanceof DigitalSample)) throw new RuntimeException("tried to call DigitalSample.glb("+s.getClass().getName()+")");
        DigitalSample ds = (DigitalSample)s;
        if (ds.value.v >= value.v && ds.strength.v >= strength.v) return this;
        if (ds.value.v <= value.v && ds.strength.v <= strength.v) return ds;
        return cache[Math.min(ds.value.v, value.v)+1][Math.min(ds.strength.v, strength.v)+1];
    }

    public double getMinValue() { return 0; }

    public double getMaxValue() { return 1; }

    public boolean isLogic0() { return value == Value.LOW; }

    public boolean isLogic1() { return value == Value.HIGH; }

    public boolean isLogicX() { return value == Value.X; }

    public boolean isLogicZ() { return value == Value.Z; }

    private byte getByteRepresentation() { return (byte)(((value.v+1) << 3) | strength.v); }

    private static DigitalSample fromByteRepresentation(byte b) { return cache[(b >> 3) & 3][b & 7]; }

    public static final Unboxed unboxer = new Unboxed()
    {
        public int getSize() { return 1; }
        public DigitalSample deserialize(byte[] buf, int ofs) { return fromByteRepresentation(buf[ofs]); }
        public void serialize(DigitalSample v, byte[] buf, int ofs) { buf[ofs] = v.getByteRepresentation(); }
    };

    private static final LatticeOperation latticeOp =
        new LatticeOperation(unboxer)
    {
        public void lub(byte[] buf1, int ofs1, byte[] buf2, int ofs2, byte[] dest, int dest_ofs)
        {
            if (((buf1[ofs1]&0xff) - (buf2[ofs2]&0xff)) < 0)
                System.arraycopy(buf2, ofs2, dest, dest_ofs, unboxer.getSize());
            else
                System.arraycopy(buf1, ofs1, dest, dest_ofs, unboxer.getSize());
        }
        public void glb(byte[] buf1, int ofs1, byte[] buf2, int ofs2, byte[] dest, int dest_ofs)
        {
            if (((buf1[ofs1]&0xff) - (buf2[ofs2]&0xff)) < 0)
                System.arraycopy(buf1, ofs1, dest, dest_ofs, unboxer.getSize());
            else
                System.arraycopy(buf2, ofs2, dest, dest_ofs, unboxer.getSize());
        }
    };

    /**
     * Method for converting ALS levels to new DigitalSample values,
     * for backward compatibility.
     * The only thing that really matters to ALS is that the four strengths:
     *           OFF_STRENGTH
     *           NODE_STRENGTH
     *           GATE_STRENGTH
     *           VDD_STRENGTH
     * be in ascending strength.
     *
     * Clearly, VDD_STRENGTH is a supply-level, so your choice of
     * SUPPLY_DRIVE seems right. Node strength is (I believe) what
     * used to be appropriate for nMOS depletion transistors
     * (i.e. stronger than a normal gate signal).  Probably your
     * choice of STRONG_PULL is also right.  Gate strength is a
     * regular signal, so your choice of LARGE_CAPACITANCE may be
     * right, or it may be PULL_DIRVE.  I don't know.  As far as
     * OFF_STRENGTH goes, why not use HIGH_IMPEDENCE?  I really don't
     * know the difference between that and SMALL_CAPACITANCE, so it's
     * your choice here.
     *    -SMR
     */
    public static DigitalSample fromOldStyle(int i)
    {
        Strength strength = null;
        Value value = null;
        switch(i & Stimuli.LOGIC)
        {
            case Stimuli.LOGIC_LOW:  value = Value.LOW; break;
            case Stimuli.LOGIC_HIGH: value = Value.HIGH; break;
            case Stimuli.LOGIC_X:    value = Value.X; break;
            case Stimuli.LOGIC_Z:    return getSample(Value.Z, Strength.HIGH_IMPEDANCE);
            default: throw new RuntimeException("unknown value: " + (i & Stimuli.LOGIC));
        }
        switch(i & Stimuli.STRENGTH)
        {
            case Stimuli.OFF_STRENGTH:  strength = Strength.SMALL_CAPACITANCE; break;
            case Stimuli.NODE_STRENGTH: strength = Strength.STRONG_PULL;       break;
            case Stimuli.GATE_STRENGTH: strength = Strength.LARGE_CAPACITANCE; break;
            case Stimuli.VDD_STRENGTH:  strength = Strength.SUPPLY_DRIVE;      break;
            default: throw new RuntimeException("unknown strength: " + (i & Stimuli.STRENGTH));
        }
        return getSample(value, strength);
    }

    public static int getState(Signal.View view, int index)
    {
        DigitalSample ds = view.getSample(index);
        return getState(ds);
    }

	public static int getState(DigitalSample ds)
	{
        if (ds.isLogic0()) return Stimuli.LOGIC_LOW;
        if (ds.isLogic1()) return Stimuli.LOGIC_HIGH;
        if (ds.isLogicX()) return Stimuli.LOGIC_X;
        if (ds.isLogicZ()) return Stimuli.LOGIC_Z;
        throw new RuntimeException("ack!");
    }

    public static MutableSignal createSignal(SignalCollection sc, Stimuli sd, String signalName, String signalContext)
    {
        return new BTreeSignal(sc, sd, signalName, signalContext, true, BTreeSignal.getTree(unboxer, latticeOp, sd))
        {
            public void plot(Panel panel, Graphics g, WaveSignal ws, Color light, List forPs,
            	Rectangle2D bounds, List selectedObjects, Signal xAxisSignal)
            {
                Dimension sz = panel.getSize();
                int hei = sz.height;

				// a simple digital signal
				int lastx = panel.getVertAxisPos();
				int lastState = 0;
                Signal ds = (Signal)ws.getSignal();
                Signal.View view = ds.getExactView();
				int numEvents = view.getNumEvents();
				int lastLowy = 0, lastHighy = 0;
				for(int i=0; i= numEvents-1)
					{
						if (g != null && !SimulationTool.isWaveformDisplayMultiState())
						{
							if (state == Stimuli.LOGIC_Z) g.setColor(Color.GREEN); else g.setColor(Color.RED);
						}
						int wid = sz.width;
						if (lowy == highy)
						{
							if (panel.processALine(g, x, lowy, wid-1, lowy, bounds, forPs, selectedObjects, ws, -1)) return;
						} else
						{
							if (panel.processABox(g, x, lowy, wid-1, highy, bounds, forPs, selectedObjects, ws, false, 0)) return;
						}
					}
					lastx = x;
					lastLowy = lowy;
					lastHighy = highy;
					lastState = state;
				}
            }
        };
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy