📄 usercom.java
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: UserCom.java * Asynchronous Logic Simulator user functions * 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.tool.simulation.Stimuli;import java.util.Iterator;/** * Class to hold user-defined functions for the ALS Simulator. */public class UserCom{ /** * Class to model a bidirectional p-channel transistor. If the * routine is called, a new node summing calculation is performed and the effects * of the gate output on the node are ignored. This algorithm is used in the * XEROX Aquarius simulation engine. * * Calling Arguments: * primHead = pointer to a structure containing the calling arguments for * the user defined function. The nodes are stored in the list * in the following order: ctl, sidea, sideb */ static class PMOSTran extends ALS.UserProc { PMOSTran(ALS als) { nameMe(als, "PMOStran"); } void simulate(ALS.Model primHead) { ALS.ALSExport ctl = primHead.exList.get(0); ALS.ALSExport [] side = new ALS.ALSExport[2]; side[0] = primHead.exList.get(1); side[1] = primHead.exList.get(2); if (ctl.nodePtr.sumState == Stimuli.LOGIC_HIGH) { scheduleNodeUpdate(primHead, side[0], '=', new Integer(Stimuli.LOGIC_X), Stimuli.OFF_STRENGTH, als.timeAbs); scheduleNodeUpdate(primHead, side[1], '=', new Integer(Stimuli.LOGIC_X), Stimuli.OFF_STRENGTH, als.timeAbs); return; } calculateBidirOutputs(primHead, side, Stimuli.GATE_STRENGTH); } } static class PMOSTranWeak extends ALS.UserProc { PMOSTranWeak(ALS als) { nameMe(als, "pMOStranWeak"); } void simulate(ALS.Model primHead) { ALS.ALSExport ctl = primHead.exList.get(0); ALS.ALSExport [] side = new ALS.ALSExport[2]; side[0] = primHead.exList.get(1); side[1] = primHead.exList.get(2); if (ctl.nodePtr.sumState == Stimuli.LOGIC_HIGH) { scheduleNodeUpdate(primHead, side[0], '=', new Integer(Stimuli.LOGIC_X), Stimuli.OFF_STRENGTH, als.timeAbs); scheduleNodeUpdate(primHead, side[1], '=', new Integer(Stimuli.LOGIC_X), Stimuli.OFF_STRENGTH, als.timeAbs); return; } calculateBidirOutputs(primHead, side, Stimuli.NODE_STRENGTH); } } /** * Class to model a bidirectional n-channel transistor. If the * routine is called, a new node summing calculation is performed and the effects * of the gate output on the node are ignored. This algorithm is used in the * XEROX Aquarius simulation engine. * * Calling Arguments: * primHead = pointer to a structure containing the calling arguments for * the user defined function. The nodes are stored in the list * in the following order: ctl, sidea, sideb */ static class NMOSTran extends ALS.UserProc { NMOSTran(ALS als) { nameMe(als, "nMOStran"); } void simulate(ALS.Model primHead) { ALS.ALSExport ctl = primHead.exList.get(0); ALS.ALSExport [] side = new ALS.ALSExport[2]; side[0] = primHead.exList.get(1); side[1] = primHead.exList.get(2); if (ctl.nodePtr.sumState == Stimuli.LOGIC_LOW) { scheduleNodeUpdate(primHead, side[0], '=', new Integer(Stimuli.LOGIC_X), Stimuli.OFF_STRENGTH, als.timeAbs); scheduleNodeUpdate(primHead, side[1], '=', new Integer(Stimuli.LOGIC_X), Stimuli.OFF_STRENGTH, als.timeAbs); return; } calculateBidirOutputs(primHead, side, Stimuli.GATE_STRENGTH); } } static class NMOSTranWeak extends ALS.UserProc { NMOSTranWeak(ALS als) { nameMe(als, "nMOStranWeak"); } void simulate(ALS.Model primHead) { ALS.ALSExport ctl = primHead.exList.get(0); ALS.ALSExport [] side = new ALS.ALSExport[2]; side[0] = primHead.exList.get(1); side[1] = primHead.exList.get(2); if (ctl.nodePtr.sumState == Stimuli.LOGIC_LOW) { scheduleNodeUpdate(primHead, side[0], '=', new Integer(Stimuli.LOGIC_X), Stimuli.OFF_STRENGTH, als.timeAbs); scheduleNodeUpdate(primHead, side[1], '=', new Integer(Stimuli.LOGIC_X), Stimuli.OFF_STRENGTH, als.timeAbs); return; } calculateBidirOutputs(primHead, side, Stimuli.NODE_STRENGTH); } } /** * Class to fake out the function of a JK flipflop. * * Calling Arguments: * primHead = pointer to a structure containing the calling arguments for * the user defined function. The nodes are stored in the list * in the following order: ck, j, k, q, qbar */ static class JKFlop extends ALS.UserProc { JKFlop(ALS als) { nameMe(als, "JKFFLOP"); } void simulate(ALS.Model primHead) { ALS.ALSExport argPtr = primHead.exList.get(0); int ck = argPtr.nodePtr.sumState; if (ck != Stimuli.LOGIC_LOW) return; argPtr = primHead.exList.get(1); int j = argPtr.nodePtr.sumState; argPtr = primHead.exList.get(2); int k = argPtr.nodePtr.sumState; argPtr = primHead.exList.get(3); ALS.ALSExport argPtrBar = primHead.exList.get(4); if (j == Stimuli.LOGIC_LOW) { if (k == Stimuli.LOGIC_LOW) return; scheduleNodeUpdate(primHead, argPtr, '=', new Integer(Stimuli.LOGIC_LOW), Stimuli.GATE_STRENGTH, als.timeAbs); scheduleNodeUpdate(primHead, argPtrBar, '=', new Integer(Stimuli.LOGIC_HIGH), Stimuli.GATE_STRENGTH, als.timeAbs); return; } if (k == Stimuli.LOGIC_LOW) { scheduleNodeUpdate(primHead, argPtr, '=', new Integer(Stimuli.LOGIC_HIGH), Stimuli.GATE_STRENGTH, als.timeAbs); scheduleNodeUpdate(primHead, argPtrBar, '=', new Integer(Stimuli.LOGIC_LOW), Stimuli.GATE_STRENGTH, als.timeAbs); return; } int out = argPtr.nodePtr.sumState; if (out == Stimuli.LOGIC_HIGH) { scheduleNodeUpdate(primHead, argPtr, '=', new Integer(Stimuli.LOGIC_LOW), Stimuli.GATE_STRENGTH, als.timeAbs); scheduleNodeUpdate(primHead, argPtrBar, '=', new Integer(Stimuli.LOGIC_HIGH), Stimuli.GATE_STRENGTH, als.timeAbs); } else { scheduleNodeUpdate(primHead, argPtr, '=', new Integer(Stimuli.LOGIC_HIGH), Stimuli.GATE_STRENGTH, als.timeAbs); scheduleNodeUpdate(primHead, argPtrBar, '=', new Integer(Stimuli.LOGIC_LOW), Stimuli.GATE_STRENGTH, als.timeAbs); } } } /** * Class to mimic the function of a D flip flop. * * Arguments: * primHead = pointer to a structure containing the * calling arguments for the user function. * The nodes are expected to appear in the * parameter list in the following order: * * dataIn, clk, q */ static class DFFlop extends ALS.UserProc { DFFlop(ALS als) { nameMe(als, "DFFLOP"); } void simulate(ALS.Model primHead) { ALS.ALSExport argPtr = primHead.exList.get(0); // dataIn signal now selected int dIn = argPtr.nodePtr.sumState; argPtr = primHead.exList.get(1); // clk signal now selected int clk = argPtr.nodePtr.sumState; // do nothing if not a +ve clock edge if (clk != Stimuli.LOGIC_LOW) return; /* If this part of the procedure has been reached, the dataOut signal should be updated since clk is high. Therefore, the value of dataOut should be set to the value of dIn (one of LOGIC_LOW, LOGIC_HIGH, or LOGIC_X). */ // select dataOut signal argPtr = primHead.exList.get(2); int q = dIn; scheduleNodeUpdate(primHead, argPtr, '=', new Integer(q), Stimuli.GATE_STRENGTH, als.timeAbs); } } /** * Class to convert the value of 8 input bits into a state * representation in the range 0x00-0xff. This function can be called for * the compact representation of the state of a bus structure in hexadecimal * format. * * Calling Arguments: * primHead = pointer to a structure containing the calling arguments for * the user defined function. The nodes are ordered b7, b6, b5, * b4, b3, b2, b1, b0, output in this list. */ static class BusToState extends ALS.UserProc { BusToState(ALS als) { nameMe(als, "BUS_TO_STATE"); } void simulate(ALS.Model primHead) { Iterator<ALS.ALSExport> it = primHead.exList.iterator(); ALS.ALSExport argPtr = it.next(); int state = 0; for (int i = 7; i > -1; --i) { int bit = argPtr.nodePtr.sumState; if (bit == Stimuli.LOGIC_HIGH) state += (0x01 << i); argPtr = it.next(); } scheduleNodeUpdate(primHead, argPtr, '=', new Integer(state), Stimuli.VDD_STRENGTH, als.timeAbs); } } /** * Class to convert a value in the range of 0x00-0xff into an 8 bit * logic representation (logic L = -1 and H = -3). This function can be called to * provide an easy means of representing bus values with a single integer entry. * * Calling Arguments: * primHead = pointer to a structure containing the calling arguments for * the user defined function. The nodes are stored in the list * in the following order: input, b7, b6, b5, b4, b3, b2, b1, b0 */ static class StateToBus extends ALS.UserProc { StateToBus(ALS als) { nameMe(als, "STATE_TO_BUS"); } void simulate(ALS.Model primHead) { Iterator<ALS.ALSExport> it = primHead.exList.iterator(); ALS.ALSExport argPtr = it.next(); int input = argPtr.nodePtr.sumState; for (int i = 7; i > -1; --i) { argPtr = it.next(); int mask = (0x01 << i); if ((input & mask) != 0) { scheduleNodeUpdate(primHead, argPtr, '=', new Integer(Stimuli.LOGIC_HIGH), Stimuli.VDD_STRENGTH, als.timeAbs); } else { scheduleNodeUpdate(primHead, argPtr, '=', new Integer(Stimuli.LOGIC_LOW), Stimuli.VDD_STRENGTH, als.timeAbs); } } } } /************************** UNUSED USER FUNCTION ROUTINES **************************/// /**// * Class fakes out the function of a synchronous reset counter.// *// * Calling Arguments:// * primHead = pointer to a structure containing the calling arguments for// * the user defined function. The nodes are stored in the list// * in the following order: ck, reset, count, out// */// static class Counter extends ALS.UserProc// {// Counter(ALS als) { nameMe(als, "COUNTER"); }//// void simulate(ALS.Model primHead)// {// ALS.ALSExport argPtr = primHead.exList.get(0);// int ck = argPtr.nodePtr.sumState;// if (ck != Stimuli.LOGIC_HIGH) return;//// argPtr = primHead.exList.get(1);// int reset = argPtr.nodePtr.sumState;// argPtr = primHead.exList.get(2);// int count = argPtr.nodePtr.sumState;// ALS.ALSExport countPtr = argPtr;// argPtr = primHead.exList.get(3);// int out = argPtr.nodePtr.sumState;//// if (reset == Stimuli.LOGIC_LOW)// {// scheduleNodeUpdate(primHead, countPtr, '=',// new Integer(0), Stimuli.GATE_STRENGTH, als.timeAbs + 30e-9);// scheduleNodeUpdate(primHead, argPtr, '=',// new Integer(Stimuli.LOGIC_LOW), Stimuli.GATE_STRENGTH, als.timeAbs + 30e-9);// return;// }//// count = (count + 1) % 16;// scheduleNodeUpdate(primHead, countPtr, '=',// new Integer(count), Stimuli.GATE_STRENGTH, als.timeAbs + 20e-9);//// if (count == 15)// {// scheduleNodeUpdate(primHead, argPtr, '=',// new Integer(Stimuli.LOGIC_HIGH), Stimuli.GATE_STRENGTH, als.timeAbs + 18e-9);// } else// {// scheduleNodeUpdate(primHead, argPtr, '=',// new Integer(Stimuli.LOGIC_LOW), Stimuli.GATE_STRENGTH, als.timeAbs + 22e-9);// }// }// }//// /**// * Class is an event driven function which is called to calculate// * the binary exponential backoff time delay for an Ethernet system.// *// * Calling Arguments:// * primHead = pointer to a structure containing the calling arguments for// * the user defined function. The nodes are stored in the list// * in the following order: retX, server// */// static class DelayCalc extends ALS.UserProc// {// DelayCalc(ALS als) { nameMe(als, "DELAY_CALC"); }//// void simulate(ALS.Model primHead)// {// double baseDelay = 10e-6;//// ALS.ALSExport retX = primHead.exList.get(0);// ALS.ALSExport server = primHead.exList.get(1);//// if (retX.nodePtr.sumState == 0) return;//// double delay = 2.0 * Math.random() * baseDelay *// (1 << (retX.nodePtr.sumState - 1)) + als.timeAbs;// scheduleNodeUpdate(primHead, server, '=',// new Integer(1), Stimuli.VDD_STRENGTH, delay);// scheduleNodeUpdate(primHead, server, '=',// new Integer(Stimuli.LOGIC_X), Stimuli.OFF_STRENGTH, delay);// }// }//// /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -