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

com.sun.electric.plugins.irsim.SStep Maven / Gradle / Ivy

/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: SStep.java
 * IRSIM simulator
 * Translated by Steven M. Rubin, Sun Microsystems.
 *
 * Copyright (C) 1988, 1990 Stanford University.
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies.  Stanford University
 * makes no representations about the suitability of this
 * software for any purpose.  It is provided "as is" without
 * express or implied warranty.
 */
package com.sun.electric.plugins.irsim;

public class SStep extends Eval
{
	SStep(Sim sim)
	{
		super(sim);
	}

	/* event-driven switch-level simulation step Chris Terman 7/84 */

	/* the following contains most of the declarations, conversion
	 * tables, etc, that depend on the particular representation chosen
	 * for node values.  This info is automatically created for interval
	 * value sets (see Chapter 5 of my thesis) by gentbl.c.  Except
	 * for the chargedState and thevValue arrays and their associated
	 * code, the rest of the code is independent of the value set details...
	 */

	/* index for each value interval */
	private static final int EMPTY	= 0;
	private static final int DH		= 1;
	private static final int DHWH	= 2;
	private static final int DHCH	= 3;
	private static final int DHcH	= 4;
	private static final int DHZ	= 5;
	private static final int DHcL	= 6;
	private static final int DHCL	= 7;
	private static final int DHWL	= 8;
	private static final int DHDL	= 9;
	private static final int WH		= 10;
	private static final int WHCH	= 11;
	private static final int WHcH	= 12;
	private static final int WHZ	= 13;
	private static final int WHcL	= 14;
	private static final int WHCL	= 15;
	private static final int WHWL	= 16;
	private static final int WHDL	= 17;
	private static final int CH		= 18;
	private static final int CHcH	= 19;
	private static final int CHZ	= 20;
	private static final int CHcL	= 21;
	private static final int CHCL	= 22;
	private static final int CHWL	= 23;
	private static final int CHDL	= 24;
	private static final int cH		= 25;
	private static final int cHZ	= 26;
	private static final int cHcL	= 27;
	private static final int cHCL	= 28;
	private static final int cHWL	= 29;
	private static final int cHDL	= 30;
	private static final int Z		= 31;
	private static final int ZcL	= 32;
	private static final int ZCL	= 33;
	private static final int ZWL	= 34;
	private static final int ZDL	= 35;
	private static final int cL		= 36;
	private static final int cLCL	= 37;
	private static final int cLWL	= 38;
	private static final int cLDL	= 39;
	private static final int CL		= 40;
	private static final int CLWL	= 41;
	private static final int CLDL	= 42;
	private static final int WL		= 43;
	private static final int WLDL	= 44;
	private static final int DL		= 45;

	private static String [] nodeValues = new String[]
	{
		"EMPTY",
		"DH",
		"DHWH",
		"DHCH",
		"DHcH",
		"DHZ",
		"DHcL",
		"DHCL",
		"DHWL",
		"DHDL",
		"WH",
		"WHCH",
		"WHcH",
		"WHZ",
		"WHcL",
		"WHCL",
		"WHWL",
		"WHDL",
		"CH",
		"CHcH",
		"CHZ",
		"CHcL",
		"CHCL",
		"CHWL",
		"CHDL",
		"cH",
		"cHZ",
		"cHcL",
		"cHCL",
		"cHWL",
		"cHDL",
		"Z",
		"ZcL",
		"ZCL",
		"ZWL",
		"ZDL",
		"cL",
		"cLCL",
		"cLWL",
		"cLDL",
		"CL",
		"CLWL",
		"CLDL",
		"WL",
		"WLDL",
		"DL"
	};

	/* conversion between interval and logic value */
	private static byte [] logicState = new byte[]
	{
		0,			/* EMPTY state */
		Sim.HIGH,	/* DH */
		Sim.HIGH,	/* DHWH */
		Sim.HIGH,	/* DHCH */
		Sim.HIGH,	/* DHcH */
		Sim.X,		/* DHZ */
		Sim.X,		/* DHcL */
		Sim.X,		/* DHCL */
		Sim.X,		/* DHWL */
		Sim.X,		/* DHDL */
		Sim.HIGH,	/* WH */
		Sim.HIGH,	/* WHCH */
		Sim.HIGH,	/* WHcH */
		Sim.X,		/* WHZ */
		Sim.X,		/* WHcL */
		Sim.X,		/* WHCL */
		Sim.X,		/* WHWL */
		Sim.X,		/* WHDL */
		Sim.HIGH,	/* CH */
		Sim.HIGH,	/* CHcH */
		Sim.X,		/* CHZ */
		Sim.X,		/* CHcL */
		Sim.X,		/* CHCL */
		Sim.X,		/* CHWL */
		Sim.X,		/* CHDL */
		Sim.HIGH,	/* cH */
		Sim.X,		/* cHZ */
		Sim.X,		/* cHcL */
		Sim.X,		/* cHCL */
		Sim.X,		/* cHWL */
		Sim.X,		/* cHDL */
		Sim.X,		/* Z */
		Sim.X,		/* ZcL */
		Sim.X,		/* ZCL */
		Sim.X,		/* ZWL */
		Sim.X,		/* ZDL */
		Sim.LOW,	/* cL */
		Sim.LOW,	/* cLCL */
		Sim.LOW,	/* cLWL */
		Sim.LOW,	/* cLDL */
		Sim.LOW,	/* CL */
		Sim.LOW,	/* CLWL */
		Sim.LOW,	/* CLDL */
		Sim.LOW,	/* WL */
		Sim.LOW,	/* WLDL */
		Sim.LOW,	/* DL */
	};

	/* transmit interval through switch */
	private static byte [][] transmit = new byte[][]
	{
		new byte[] {0, 0,	   0,    0},	/* EMPTY state */
		new byte[] {Z, DH,   DHZ,  WH},		/* DH */
		new byte[] {Z, DHWH, DHZ,  WH},		/* DHWH */
		new byte[] {Z, DHCH, DHZ,  WHCH},	/* DHCH */
		new byte[] {Z, DHcH, DHZ,  WHcH},	/* DHcH */
		new byte[] {Z, DHZ,  DHZ,  WHZ},	/* DHZ */
		new byte[] {Z, DHcL, DHcL, WHcL},	/* DHcL */
		new byte[] {Z, DHCL, DHCL, WHCL},	/* DHCL */
		new byte[] {Z, DHWL, DHWL, WHWL},	/* DHWL */
		new byte[] {Z, DHDL, DHDL, WHWL},	/* DHDL */
		new byte[] {Z, WH,   WHZ,  WH},		/* WH */
		new byte[] {Z, WHCH, WHZ,  WHCH},	/* WHCH */
		new byte[] {Z, WHcH, WHZ,  WHcH},	/* WHcH */
		new byte[] {Z, WHZ,  WHZ,  WHZ},	/* WHZ */
		new byte[] {Z, WHcL, WHcL, WHcL},	/* WHcL */
		new byte[] {Z, WHCL, WHCL, WHCL},	/* WHCL */
		new byte[] {Z, WHWL, WHWL, WHWL},	/* WHWL */
		new byte[] {Z, WHDL, WHDL, WHWL},	/* WHDL */
		new byte[] {Z, CH,   CHZ,  CH},		/* CH */
		new byte[] {Z, CHcH, CHZ,  CHcH},	/* CHcH */
		new byte[] {Z, CHZ,  CHZ,  CHZ},	/* CHZ */
		new byte[] {Z, CHcL, CHcL, CHcL},	/* CHcL */
		new byte[] {Z, CHCL, CHCL, CHCL},	/* CHCL */
		new byte[] {Z, CHWL, CHWL, CHWL},	/* CHWL */
		new byte[] {Z, CHDL, CHDL, CHWL},	/* CHDL */
		new byte[] {Z, cH,   cHZ,  cH},		/* cH */
		new byte[] {Z, cHZ,  cHZ,  cHZ},	/* cHZ */
		new byte[] {Z, cHcL, cHcL, cHcL},	/* cHcL */
		new byte[] {Z, cHCL, cHCL, cHCL},	/* cHCL */
		new byte[] {Z, cHWL, cHWL, cHWL},	/* cHWL */
		new byte[] {Z, cHDL, cHDL, cHWL},	/* cHDL */
		new byte[] {Z, Z,    Z,    Z},		/* Z */
		new byte[] {Z, ZcL,  ZcL,  ZcL},	/* ZcL */
		new byte[] {Z, ZCL,  ZCL,  ZCL},	/* ZCL */
		new byte[] {Z, ZWL,  ZWL,  ZWL},	/* ZWL */
		new byte[] {Z, ZDL,  ZDL,  ZWL},	/* ZDL */
		new byte[] {Z, cL,   ZcL,  cL},		/* cL */
		new byte[] {Z, cLCL, ZCL,  cLCL},	/* cLCL */
		new byte[] {Z, cLWL, ZWL,  cLWL},	/* cLWL */
		new byte[] {Z, cLDL, ZDL,  cLWL},	/* cLDL */
		new byte[] {Z, CL,   ZCL,  CL},		/* CL */
		new byte[] {Z, CLWL, ZWL,  CLWL},	/* CLWL */
		new byte[] {Z, CLDL, ZDL,  CLWL},	/* CLDL */
		new byte[] {Z, WL,   ZWL,  WL},		/* WL */
		new byte[] {Z, WLDL, ZDL,  WL},		/* WLDL */
		new byte[] {Z, DL,   ZDL,  WL}		/* DL */
	};

	/* tables for converting node value to corresponding charged state */
	private static	byte [] chargedState = new byte[] {CL, CHCL, CHCL, CH};
	private static	byte [] xChargedState = new byte[] {cL, cHcL, cHcL, cH};

	/* table for converting node value to corresponding value state */
	private static	byte [] thevValue = new byte[] {DL, DHDL, DHDL, DH};

	/* result of shorting two intervals */
	private static byte [][] sMerge = new byte[][]
	{
	/* EMPTY state */
	  new byte[] {0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0},
	/* DH */
	  new byte[] {0,  DH,  DH,  DH,  DH,  DH,  DH,  DH,
	  DH,  DHDL,  DH,  DH,  DH,  DH,  DH,  DH,
	  DH,  DHDL,  DH,  DH,  DH,  DH,  DH,  DH,
	  DHDL,  DH,  DH,  DH,  DH,  DH,  DHDL,  DH,
	  DH,  DH,  DH,  DHDL,  DH,  DH,  DH,  DHDL,
	  DH,  DH,  DHDL,  DH,  DHDL,  DHDL},
	/* DHWH */
	  new byte[] {0,  DH,  DHWH,  DHWH,  DHWH,  DHWH,  DHWH,  DHWH,
	  DHWL,  DHDL,  DHWH,  DHWH,  DHWH,  DHWH,  DHWH,  DHWH,
	  DHWL,  DHDL,  DHWH,  DHWH,  DHWH,  DHWH,  DHWH,  DHWL,
	  DHDL,  DHWH,  DHWH,  DHWH,  DHWH,  DHWL,  DHDL,  DHWH,
	  DHWH,  DHWH,  DHWL,  DHDL,  DHWH,  DHWH,  DHWL,  DHDL,
	  DHWH,  DHWL,  DHDL,  DHWL,  DHDL,  DHDL},
	/* DHCH */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHCH,  DHCH,  DHCH,  DHCL,
	  DHWL,  DHDL,  DHWH,  DHCH,  DHCH,  DHCH,  DHCH,  DHCL,
	  DHWL,  DHDL,  DHCH,  DHCH,  DHCH,  DHCH,  DHCL,  DHWL,
	  DHDL,  DHCH,  DHCH,  DHCH,  DHCL,  DHWL,  DHDL,  DHCH,
	  DHCH,  DHCL,  DHWL,  DHDL,  DHCH,  DHCL,  DHWL,  DHDL,
	  DHCL,  DHWL,  DHDL,  DHWL,  DHDL,  DHDL},
	/* DHcH */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcH,  DHcH,  DHcL,  DHCL,
	  DHWL,  DHDL,  DHWH,  DHCH,  DHcH,  DHcH,  DHcL,  DHCL,
	  DHWL,  DHDL,  DHCH,  DHcH,  DHcH,  DHcL,  DHCL,  DHWL,
	  DHDL,  DHcH,  DHcH,  DHcL,  DHCL,  DHWL,  DHDL,  DHcH,
	  DHcL,  DHCL,  DHWL,  DHDL,  DHcL,  DHCL,  DHWL,  DHDL,
	  DHCL,  DHWL,  DHDL,  DHWL,  DHDL,  DHDL},
	/* DHZ */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcH,  DHZ,  DHcL,  DHCL,
	  DHWL,  DHDL,  DHWH,  DHCH,  DHcH,  DHZ,  DHcL,  DHCL,
	  DHWL,  DHDL,  DHCH,  DHcH,  DHZ,  DHcL,  DHCL,  DHWL,
	  DHDL,  DHcH,  DHZ,  DHcL,  DHCL,  DHWL,  DHDL,  DHZ,
	  DHcL,  DHCL,  DHWL,  DHDL,  DHcL,  DHCL,  DHWL,  DHDL,
	  DHCL,  DHWL,  DHDL,  DHWL,  DHDL,  DHDL},
	/* DHcL */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcL,  DHcL,  DHcL,  DHCL,
	  DHWL,  DHDL,  DHWH,  DHCH,  DHcL,  DHcL,  DHcL,  DHCL,
	  DHWL,  DHDL,  DHCH,  DHcL,  DHcL,  DHcL,  DHCL,  DHWL,
	  DHDL,  DHcL,  DHcL,  DHcL,  DHCL,  DHWL,  DHDL,  DHcL,
	  DHcL,  DHCL,  DHWL,  DHDL,  DHcL,  DHCL,  DHWL,  DHDL,
	  DHCL,  DHWL,  DHDL,  DHWL,  DHDL,  DHDL},
	/* DHCL */
	  new byte[] {0,  DH,  DHWH,  DHCL,  DHCL,  DHCL,  DHCL,  DHCL,
	  DHWL,  DHDL,  DHWH,  DHCL,  DHCL,  DHCL,  DHCL,  DHCL,
	  DHWL,  DHDL,  DHCL,  DHCL,  DHCL,  DHCL,  DHCL,  DHWL,
	  DHDL,  DHCL,  DHCL,  DHCL,  DHCL,  DHWL,  DHDL,  DHCL,
	  DHCL,  DHCL,  DHWL,  DHDL,  DHCL,  DHCL,  DHWL,  DHDL,
	  DHCL,  DHWL,  DHDL,  DHWL,  DHDL,  DHDL},
	/* DHWL */
	  new byte[] {0,  DH,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHWL,  DHDL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHWL,  DHDL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHDL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHDL,  DHWL,
	  DHWL,  DHWL,  DHWL,  DHDL,  DHWL,  DHWL,  DHWL,  DHDL,
	  DHWL,  DHWL,  DHDL,  DHWL,  DHDL,  DHDL},
	/* DHDL */
	  new byte[] {0,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL},
	/* WH */
	  new byte[] {0,  DH,  DHWH,  DHWH,  DHWH,  DHWH,  DHWH,  DHWH,
	  DHWL,  DHDL,  WH,  WH,  WH,  WH,  WH,  WH,
	  WHWL,  WHDL,  WH,  WH,  WH,  WH,  WH,  WHWL,
	  WHDL,  WH,  WH,  WH,  WH,  WHWL,  WHDL,  WH,
	  WH,  WH,  WHWL,  WHDL,  WH,  WH,  WHWL,  WHDL,
	  WH,  WHWL,  WHDL,  WHWL,  WHDL,  DL},
	/* WHCH */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHCH,  DHCH,  DHCH,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHCH,  WHCH,  WHCH,  WHCL,
	  WHWL,  WHDL,  WHCH,  WHCH,  WHCH,  WHCH,  WHCL,  WHWL,
	  WHDL,  WHCH,  WHCH,  WHCH,  WHCL,  WHWL,  WHDL,  WHCH,
	  WHCH,  WHCL,  WHWL,  WHDL,  WHCH,  WHCL,  WHWL,  WHDL,
	  WHCL,  WHWL,  WHDL,  WHWL,  WHDL,  DL},
	/* WHcH */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcH,  DHcH,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcH,  WHcH,  WHcL,  WHCL,
	  WHWL,  WHDL,  WHCH,  WHcH,  WHcH,  WHcL,  WHCL,  WHWL,
	  WHDL,  WHcH,  WHcH,  WHcL,  WHCL,  WHWL,  WHDL,  WHcH,
	  WHcL,  WHCL,  WHWL,  WHDL,  WHcL,  WHCL,  WHWL,  WHDL,
	  WHCL,  WHWL,  WHDL,  WHWL,  WHDL,  DL},
	/* WHZ */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcH,  DHZ,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcH,  WHZ,  WHcL,  WHCL,
	  WHWL,  WHDL,  WHCH,  WHcH,  WHZ,  WHcL,  WHCL,  WHWL,
	  WHDL,  WHcH,  WHZ,  WHcL,  WHCL,  WHWL,  WHDL,  WHZ,
	  WHcL,  WHCL,  WHWL,  WHDL,  WHcL,  WHCL,  WHWL,  WHDL,
	  WHCL,  WHWL,  WHDL,  WHWL,  WHDL,  DL},
	/* WHcL */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcL,  DHcL,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcL,  WHcL,  WHcL,  WHCL,
	  WHWL,  WHDL,  WHCH,  WHcL,  WHcL,  WHcL,  WHCL,  WHWL,
	  WHDL,  WHcL,  WHcL,  WHcL,  WHCL,  WHWL,  WHDL,  WHcL,
	  WHcL,  WHCL,  WHWL,  WHDL,  WHcL,  WHCL,  WHWL,  WHDL,
	  WHCL,  WHWL,  WHDL,  WHWL,  WHDL,  DL},
	/* WHCL */
	  new byte[] {0,  DH,  DHWH,  DHCL,  DHCL,  DHCL,  DHCL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCL,  WHCL,  WHCL,  WHCL,  WHCL,
	  WHWL,  WHDL,  WHCL,  WHCL,  WHCL,  WHCL,  WHCL,  WHWL,
	  WHDL,  WHCL,  WHCL,  WHCL,  WHCL,  WHWL,  WHDL,  WHCL,
	  WHCL,  WHCL,  WHWL,  WHDL,  WHCL,  WHCL,  WHWL,  WHDL,
	  WHCL,  WHWL,  WHDL,  WHWL,  WHDL,  DL},
	/* WHWL */
	  new byte[] {0,  DH,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHWL,  DHDL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,
	  WHWL,  WHDL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,
	  WHDL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,  WHDL,  WHWL,
	  WHWL,  WHWL,  WHWL,  WHDL,  WHWL,  WHWL,  WHWL,  WHDL,
	  WHWL,  WHWL,  WHDL,  WHWL,  WHDL,  DL},
	/* WHDL */
	  new byte[] {0,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  DL},
	/* CH */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHCH,  DHCH,  DHCH,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHCH,  WHCH,  WHCH,  WHCL,
	  WHWL,  WHDL,  CH,  CH,  CH,  CH,  CHCL,  CHWL,
	  CHDL,  CH,  CH,  CH,  CHCL,  CHWL,  CHDL,  CH,
	  CH,  CHCL,  CHWL,  CHDL,  CH,  CHCL,  CHWL,  CHDL,
	  CHCL,  CHWL,  CHDL,  WL,  WLDL,  DL},
	/* CHcH */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcH,  DHcH,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcH,  WHcH,  WHcL,  WHCL,
	  WHWL,  WHDL,  CH,  CHcH,  CHcH,  CHcL,  CHCL,  CHWL,
	  CHDL,  CHcH,  CHcH,  CHcL,  CHCL,  CHWL,  CHDL,  CHcH,
	  CHcL,  CHCL,  CHWL,  CHDL,  CHcL,  CHCL,  CHWL,  CHDL,
	  CHCL,  CHWL,  CHDL,  WL,  WLDL,  DL},
	/* CHZ */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcH,  DHZ,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcH,  WHZ,  WHcL,  WHCL,
	  WHWL,  WHDL,  CH,  CHcH,  CHZ,  CHcL,  CHCL,  CHWL,
	  CHDL,  CHcH,  CHZ,  CHcL,  CHCL,  CHWL,  CHDL,  CHZ,
	  CHcL,  CHCL,  CHWL,  CHDL,  CHcL,  CHCL,  CHWL,  CHDL,
	  CHCL,  CHWL,  CHDL,  WL,  WLDL,  DL},
	/* CHcL */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcL,  DHcL,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcL,  WHcL,  WHcL,  WHCL,
	  WHWL,  WHDL,  CH,  CHcL,  CHcL,  CHcL,  CHCL,  CHWL,
	  CHDL,  CHcL,  CHcL,  CHcL,  CHCL,  CHWL,  CHDL,  CHcL,
	  CHcL,  CHCL,  CHWL,  CHDL,  CHcL,  CHCL,  CHWL,  CHDL,
	  CHCL,  CHWL,  CHDL,  WL,  WLDL,  DL},
	/* CHCL */
	  new byte[] {0,  DH,  DHWH,  DHCL,  DHCL,  DHCL,  DHCL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCL,  WHCL,  WHCL,  WHCL,  WHCL,
	  WHWL,  WHDL,  CHCL,  CHCL,  CHCL,  CHCL,  CHCL,  CHWL,
	  CHDL,  CHCL,  CHCL,  CHCL,  CHCL,  CHWL,  CHDL,  CHCL,
	  CHCL,  CHCL,  CHWL,  CHDL,  CHCL,  CHCL,  CHWL,  CHDL,
	  CHCL,  CHWL,  CHDL,  WL,  WLDL,  DL},
	/* CHWL */
	  new byte[] { 0,  DH,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHWL,  DHDL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,
	  WHWL,  WHDL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,
	  CHDL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,  CHDL,  CHWL,
	  CHWL,  CHWL,  CHWL,  CHDL,  CHWL,  CHWL,  CHWL,  CHDL,
	  CHWL,  CHWL,  CHDL,  WL,  WLDL,  DL},
	/* CHDL */
	  new byte[] {0,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,
	  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,
	  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,
	  CHDL,  CHDL,  CHDL,  WLDL,  WLDL,  DL},
	/* cH */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcH,  DHcH,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcH,  WHcH,  WHcL,  WHCL,
	  WHWL,  WHDL,  CH,  CHcH,  CHcH,  CHcL,  CHCL,  CHWL,
	  CHDL,  cH,  cH,  cHcL,  cHCL,  cHWL,  cHDL,  cH,
	  cHcL,  cHCL,  cHWL,  cHDL,  cHcL,  cHCL,  cHWL,  cHDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* cHZ */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcH,  DHZ,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcH,  WHZ,  WHcL,  WHCL,
	  WHWL,  WHDL,  CH,  CHcH,  CHZ,  CHcL,  CHCL,  CHWL,
	  CHDL,  cH,  cHZ,  cHcL,  cHCL,  cHWL,  cHDL,  cHZ,
	  cHcL,  cHCL,  cHWL,  cHDL,  cHcL,  cHCL,  cHWL,  cHDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* cHcL */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcL,  DHcL,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcL,  WHcL,  WHcL,  WHCL,
	  WHWL,  WHDL,  CH,  CHcL,  CHcL,  CHcL,  CHCL,  CHWL,
	  CHDL,  cHcL,  cHcL,  cHcL,  cHCL,  cHWL,  cHDL,  cHcL,
	  cHcL,  cHCL,  cHWL,  cHDL,  cHcL,  cHCL,  cHWL,  cHDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* cHCL */
	  new byte[] {0,  DH,  DHWH,  DHCL,  DHCL,  DHCL,  DHCL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCL,  WHCL,  WHCL,  WHCL,  WHCL,
	  WHWL,  WHDL,  CHCL,  CHCL,  CHCL,  CHCL,  CHCL,  CHWL,
	  CHDL,  cHCL,  cHCL,  cHCL,  cHCL,  cHWL,  cHDL,  cHCL,
	  cHCL,  cHCL,  cHWL,  cHDL,  cHCL,  cHCL,  cHWL,  cHDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* cHWL */
	  new byte[] {0,  DH,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHWL,  DHDL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,
	  WHWL,  WHDL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,
	  CHDL,  cHWL,  cHWL,  cHWL,  cHWL,  cHWL,  cHDL,  cHWL,
	  cHWL,  cHWL,  cHWL,  cHDL,  cHWL,  cHWL,  cHWL,  cHDL,
	  CLWL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* cHDL */
	  new byte[] {0,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,
	  CHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,
	  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,
	  CLDL,  CLDL,  CLDL,  WLDL,  WLDL,  DL},
	/* Z */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcH,  DHZ,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcH,  WHZ,  WHcL,  WHCL,
	  WHWL,  WHDL,  CH,  CHcH,  CHZ,  CHcL,  CHCL,  CHWL,
	  CHDL,  cH,  cHZ,  cHcL,  cHCL,  cHWL,  cHDL,  Z,
	  ZcL,  ZCL,  ZWL,  ZDL,  cL,  cLCL,  cLWL,  cLDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* ZcL */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcL,  DHcL,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcL,  WHcL,  WHcL,  WHCL,
	  WHWL,  WHDL,  CH,  CHcL,  CHcL,  CHcL,  CHCL,  CHWL,
	  CHDL,  cHcL,  cHcL,  cHcL,  cHCL,  cHWL,  cHDL,  ZcL,
	  ZcL,  ZCL,  ZWL,  ZDL,  cL,  cLCL,  cLWL,  cLDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* ZCL */
	  new byte[] {0,  DH,  DHWH,  DHCL,  DHCL,  DHCL,  DHCL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCL,  WHCL,  WHCL,  WHCL,  WHCL,
	  WHWL,  WHDL,  CHCL,  CHCL,  CHCL,  CHCL,  CHCL,  CHWL,
	  CHDL,  cHCL,  cHCL,  cHCL,  cHCL,  cHWL,  cHDL,  ZCL,
	  ZCL,  ZCL,  ZWL,  ZDL,  cLCL,  cLCL,  cLWL,  cLDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* ZWL */
	  new byte[] {0,  DH,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHWL,  DHDL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,
	  WHWL,  WHDL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,
	  CHDL,  cHWL,  cHWL,  cHWL,  cHWL,  cHWL,  cHDL,  ZWL,
	  ZWL,  ZWL,  ZWL,  ZDL,  cLWL,  cLWL,  cLWL,  cLDL,
	  CLWL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* ZDL */
	  new byte[] {0,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,
	  CHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,  ZDL,
	  ZDL,  ZDL,  ZDL,  ZDL,  cLDL,  cLDL,  cLDL,  cLDL,
	  CLDL,  CLDL,  CLDL,  WLDL,  WLDL,  DL},
	/* cL */
	  new byte[] {0,  DH,  DHWH,  DHCH,  DHcL,  DHcL,  DHcL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCH,  WHcL,  WHcL,  WHcL,  WHCL,
	  WHWL,  WHDL,  CH,  CHcL,  CHcL,  CHcL,  CHCL,  CHWL,
	  CHDL,  cHcL,  cHcL,  cHcL,  cHCL,  cHWL,  cHDL,  cL,
	  cL,  cLCL,  cLWL,  cLDL,  cL,  cLCL,  cLWL,  cLDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* cLCL */
	  new byte[] {0,  DH,  DHWH,  DHCL,  DHCL,  DHCL,  DHCL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCL,  WHCL,  WHCL,  WHCL,  WHCL,
	  WHWL,  WHDL,  CHCL,  CHCL,  CHCL,  CHCL,  CHCL,  CHWL,
	  CHDL,  cHCL,  cHCL,  cHCL,  cHCL,  cHWL,  cHDL,  cLCL,
	  cLCL,  cLCL,  cLWL,  cLDL,  cLCL,  cLCL,  cLWL,  cLDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* cLWL */
	  new byte[] {0,  DH,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHWL,  DHDL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,
	  WHWL,  WHDL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,
	  CHDL,  cHWL,  cHWL,  cHWL,  cHWL,  cHWL,  cHDL,  cLWL,
	  cLWL,  cLWL,  cLWL,  cLDL,  cLWL,  cLWL,  cLWL,  cLDL,
	  CLWL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* cLDL */
	  new byte[] {0,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,
	  CHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cHDL,  cLDL,
	  cLDL,  cLDL,  cLDL,  cLDL,  cLDL,  cLDL,  cLDL,  cLDL,
	  CLDL,  CLDL,  CLDL,  WLDL,  WLDL,  DL},
	/* CL */
	  new byte[] {0,  DH,  DHWH,  DHCL,  DHCL,  DHCL,  DHCL,  DHCL,
	  DHWL,  DHDL,  WH,  WHCL,  WHCL,  WHCL,  WHCL,  WHCL,
	  WHWL,  WHDL,  CHCL,  CHCL,  CHCL,  CHCL,  CHCL,  CHWL,
	  CHDL,  CL,  CL,  CL,  CL,  CLWL,  CLDL,  CL,
	  CL,  CL,  CLWL,  CLDL,  CL,  CL,  CLWL,  CLDL,
	  CL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* CLWL */
	  new byte[] {0,  DH,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHWL,  DHDL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,
	  WHWL,  WHDL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,  CHWL,
	  CHDL,  CLWL,  CLWL,  CLWL,  CLWL,  CLWL,  CLDL,  CLWL,
	  CLWL,  CLWL,  CLWL,  CLDL,  CLWL,  CLWL,  CLWL,  CLDL,
	  CLWL,  CLWL,  CLDL,  WL,  WLDL,  DL},
	/* CLDL */
	  new byte[] {0,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,  CHDL,
	  CHDL,  CLDL,  CLDL,  CLDL,  CLDL,  CLDL,  CLDL,  CLDL,
	  CLDL,  CLDL,  CLDL,  CLDL,  CLDL,  CLDL,  CLDL,  CLDL,
	  CLDL,  CLDL,  CLDL,  WLDL,  WLDL,  DL},
	/* WL */
	  new byte[] {0,  DH,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,  DHWL,
	  DHWL,  DHDL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,  WHWL,
	  WHWL,  WHDL,  WL,  WL,  WL,  WL,  WL,  WL,
	  WLDL,  WL,  WL,  WL,  WL,  WL,  WLDL,  WL,
	  WL,  WL,  WL,  WLDL,  WL,  WL,  WL,  WLDL,
	  WL,  WL,  WLDL,  WL,  WLDL,  DL},
	/* WLDL */
	  new byte[] {0,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,  WHDL,
	  WHDL,  WHDL,  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,
	  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,
	  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,
	  WLDL,  WLDL,  WLDL,  WLDL,  WLDL,  DL},
	/* DL */
	  new byte[] {0,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,  DHDL,
	  DHDL,  DHDL,  DL,  DL,  DL,  DL,  DL,  DL,
	  DL,  DL,  DL,  DL,  DL,  DL,  DL,  DL,
	  DL,  DL,  DL,  DL,  DL,  DL,  DL,  DL,
	  DL,  DL,  DL,  DL,  DL,  DL,  DL,  DL,
	  DL,  DL,  DL,  DL,  DL,  DL}
	};

	/**
	 * calculate new value for node and its electrical neighbor
	 */
	public void modelEvaluate(Sim.Node n)
	{
		if ((n.nFlags & Sim.VISITED) != 0)
			theSim.buildConnList(n);

		/* for each node on list we just built, recompute its value using a
		 * recursive tree walk.  If logic state of new value differs from
		 * logic state of current value, node is added to the event list (or
		 * if it's already there, just the eval field is updated).  If logic
		 * states do not differ, node's value is updated on the spot and any
		 * pending events removed.
		 */
		for(Sim.Node thisOne = n; thisOne != null; thisOne = thisOne.nLink)
		{
			int newVal = 0;
			long tau = 0, delta = 0;
			if ((thisOne.nFlags & Sim.INPUT) != 0)
				newVal = thisOne.nPot;
			else
			{
				newVal = logicState[scThev(thisOne, (thisOne.nFlags & Sim.WATCHED) != 0 ? 1 : 0)];
				switch(newVal)
				{
					case Sim.LOW:
						delta = thisOne.tpHL;
						break;
					case Sim.X:
						delta = 0;
						break;
					case Sim.HIGH:
						delta = thisOne.tpLH;
						break;
				}
				tau = delta;
				if (delta == 0)	// no zero-delay events
					delta = 1;
			}

			if ((thisOne.nFlags & Sim.INPUT) == 0)
			{
				// Check to see if this new value invalidates other events.
				// Since this event has newer info about the state of the network,
				// delete transitions scheduled to come after it.
				Event e;
				while((e = thisOne.events) != null && e.nTime >= theSim.curDelta + delta)
				{
					/*
					 * Do not try to kick the event scheduled at Sched.curDelta if
					 * newVal is equal to this.nPot because that event sets
					 * this.nPot, but its consequences has not been handled yet.
					 * Besides, this event will not be queued.
					 *
					 * However, if there is event scheduled now but driving to a
					 * different value, then kick it because we will enqueue this
					 * one, and source/drain of transistors controlled by this
					 * node will be re-evaluated. At worst, some extra computation
					 * will be carried out due to VISITED flags set previously.
					 */
					/*		if (e.nTime == Sched.curDelta and newVal == thisOne.nPot) */
					if (e.nTime == (theSim.curDelta + delta) && e.eval == newVal)
						break;
					puntEvent(thisOne, e);
				}

				// Now see if the new value is different from the last value
				// scheduled for the node. If there are no pending events then
				// just use the current value.
				boolean queued = false;
				if (newVal != ((e == null) ? thisOne.nPot : e.eval))
				{
					queued = true;
					enqueueEvent(thisOne, newVal, delta, tau);
				}

				if ((thisOne.nFlags & Sim.WATCHED) != 0 && (theSim.irDebug & (Sim.DEBUG_DC | Sim.DEBUG_EV)) != 0)
				{
					System.out.println(" [event " + theSim.curNode.nName + "->" +
						Sim.vChars.charAt(theSim.curNode.nPot) + " @ " +
						Sim.deltaToNS(theSim.curDelta) + "] ");

					System.out.println(queued ? "causes transition for" : "sets");
					System.out.println(" " + thisOne.nName + ": " + Sim.vChars.charAt(thisOne.nPot) + " -> " +
						Sim.vChars.charAt(newVal) + " (delay = " + Sim.deltaToNS(delta) + "ns)");
				}
			}
		}

		// undo connection list
		Sim.Node next = null;
		for(Sim.Node thisOne = n; thisOne != null; thisOne = next)
		{
			next = thisOne.nLink;
			thisOne.nLink = null;
		}
	}

	/**
	 * compute new value for a node using recursive tree walk.  We start off by
	 * assuming that node is charged to whatever logic state it had last.  The
	 * contribution of each path leading away from the node is computed
	 * recursively and merged with accumulated result.  After all paths have been
	 * examined, return the answer!
	 *
	 * Notes: The node-visited flag is set during the computation of a node's
	 *	  value. This keeps the tree walk expanding outward; loops are avoided.
	 *	  Since the flag is cleared at the end of the computation, all paths
	 *	  through the network will eventually be explored.  (If it had been
	 *	  left set, only a single path through a particular cycle would be
	 *	  explored).
	 *
	 *        In order to speed up the computation, the result of each recursive
	 *	  call is cached.  There are 2 caches associated with each transistor:
	 *	  the source cache remembers the value of the subnetwork that includes
	 *	  the transistor and everything attached to its drain. The drain cache
	 *	  is symmetrical.  Use of these caches reduces the complexity of the
	 *	  new-value computation from O(n**2) to O(n) where n is the number of
	 *	  nodes in the connection list built in the new_value routine.
	 */
	private int scThev(Sim.Node n, int level)
	{
		int result = 0;
		if ((n.nFlags & Sim.INPUT) != 0)
		{
			result = thevValue[n.nPot];
		} else
		{
			// initial values and stuff...
			n.nFlags |= Sim.VISITED;
			result = (n.nGateList.size() == 0) ? xChargedState[n.nPot] : chargedState[n.nPot];

			for(Sim.Trans t : n.nTermList)
			{
				// don't bother with off transistors
				if (t.state == Sim.OFF) continue;

				// for each non-off transistor, do nothing if node on other side has
				// its visited flag set (this is how cycles are detected).  Otherwise
				// check cache and use value found there, if any.  As a last resort,
				// actually compute value for network on other side of transistor,
				// transmit the value through the transistor, and save that result
				// for later use.
				if (n == t.source)
				{
					if ((t.drain.nFlags & Sim.VISITED) == 0)
					{
						if (t.getDI() == EMPTY)
							t.setDI(transmit[scThev(t.drain, level != 0 ? level + 1 : 0)][t.state]);
						result = sMerge[result][t.getDI()];
					}
				} else
				{
					if ((t.source.nFlags & Sim.VISITED) == 0)
					{
						if (t.getSI() == EMPTY)
							t.setSI( transmit[scThev(t.source, level != 0 ? level + 1 : 0)][t.state]);
						result = sMerge[result][t.getSI()];
					}
				}
			}

			n.nFlags &= ~Sim.VISITED;
		}
		if ((theSim.irDebug & (Sim.DEBUG_DC | Sim.DEBUG_TW)) != 0 && level > 0)
		{
			System.out.print("  ");
			for(int i = level; --i > 0; )
				System.out.print(" ");
			System.out.println("scThev(" + n.nName + ") = " + nodeValues[result]);
		}

		return result;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy