Mixed Signal Microcontroller Simulator      

   ECE492 Project by Engin Ipek Advisor: Bruce Land

Introduction                          High Level Design                           Results                       Netlist Files               Mask Files                 MCU Models            Listing                       

 Improvements

 Introduction:

 The purpose of this project was to extend the Mixed Signal AVR simulator written in Fall’02 so that any single-issue microprocessor could be included in the simulation environment rather than limiting the simulations to systems based around ATMEL AT90S8515 series microcontrollers. In order to achieve this goal, a general architectural description language (ADL) simulator was written and the user was provided with abtractions that allow the full specification of a microcontroller model and the corresponding memory hierarchy. Furthermore, the capabilities of the pre-existing simulator were extended to handle multiple microcontrollers at the same time. The final version of the mixed-signal MCU simulator was tested by implementing a 32-bit, single-issue MIPS microprocessor and L1-cache system. The correctness of this model was verified by comparing against a Verilog model of the same processor. In order to verify the operation of the ADL – Analog interface of the extended simulator, two instances of the MIPS processor were included in a sinewave-generator and run in parallel. Test results showed that the extended version of the simulator successfully handled two MIPS MCU’s running in parallel in a mixed-signal environment.

High Level Design:

 

The final version of the simulator was written entirely in Java programming language. The code was organized roughly as depicted in the figure below, where each box represents a class and arrows denote the interaction of one class with another.  On each arrow, outputs of one type of object that are passed to another object as inputs are shown (eg, the parser passes an array of logic elements to class Logic). For simplicity, only the major classes and the main inputs/outputs of those classes are shown, while a complete listing of the code can be found under the listing section.

 

 

 

 


                                                                                   

                                                                                                 -Program Organization-

 

 The major difference between the current and the previous versions of the project is that the Hex File Reader has been replaced by the ADLSimulator class.

The ADLSimulator is the superclass of all MCU models and is intended to hide the unnecessary details of cycle-accurate simulation and analog – digital interfacing from the user. The ADLSimulator takes the MCU models, the states of the instruction memories at time t=0, and mask files as inputs. It generates instances of the models referenced in the netlist files and loads these models with the proper instructions. The loaded models are passed to the solver class.

Aside form this difference, the solver and the compiler classes were modified significantly to handle general CPU models rather than the hardcoded 8515 model, and further modifications to these files were made to simulate an arbitrary number of CPUs oncurrently. However, the basic working principles of the simulator, the analog-digital interfaces and the algorithms used for analog simulation have remained unchanged.

 

Results:

 

In order to test the operation of the simulator, two MIPS models were run in parallel in a sinewave – generator application. The first processor was used to generate the sinewave by performing memory mapped I/O. Memory address 0 was declared as a port in the netlist file, and this PORT was connected to the rest of the analog circuitry as shown below.  In order to test correct parallel operation, the second CPU was loaded with instructions that toggle the memory location 0 between 0 and 1. for the second CPU, the least significant bit of memory location 0 was declared as a port and connected to ground through a 1K resistor (not shown). The netlist file that describes the se connections is shown below. The assembly instructions running on the processors is also listed. The corresponding MIPS model is included in the listing section.

 

R 1 9 20000

R 9 0 20000

R 2 10 20000

R 3 11 20000

R 4 12 20000

R 5 13 20000

R 6 14 20000

R 7 15 20000

R 8 16 20000

R 9 10 10000

R 10 11 10000

R 11 12 10000

R 12 13 10000

R 13 14 10000

R 14 15 10000

R 15 16 10000

PORT 1 0 0 cpu1            

PORT 2 0 1 cpu1              

PORT 3 0 2 cpu1                  

PORT 4 0 3 cpu1                

PORT 5 0 4 cpu1             

PORT 6 0 5 cpu1                  

PORT 7 0 6 cpu1                  

PORT 8 0 7 cpu1

PORT 19 0 0 cpu2

R 0 19 1000

OPAMP 17 0 18

R 17 18 2000000          

R 18 0 1000

R 16 17 1000000

AND 1 2 20

OR  3 20 21

DUMPLOGIC logicOUT 21 ENDDUMP

DUMP cpu1 portc 0 R0 0 R1 1 R2 2 R3 3 R4 5 R5 5 R6 6 R7 7 R8 8 R9 9 ENDDUMP

DUMP cpu2 reg2 0 ENDDUMP

DUMPANALOG opAmpOut1 18 bit0 19 dacOut 16 zeroOut 9 opAmpNegTerminal 17 ENDDUMP

end   

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


The netlist file describing the hardware in the schematics is provided at the right.

The first lines describe an R-2R ladder DAC, followed by the connections to the first

cpu and the logic gates. This is followed by the port declaration for the second cpu.

The dump statements at the end specify the nodes whose values are to be stored into

excel and vcd files for viewing after the simulation. These nodes are also named in the body of

the dump statements to facilitate the viewing process. A more detailed explanation

of the changes to the netlist file format can be found under the netlist files section.



The MIPS assembly instructions running on the two processors are listed below. The code was assembled using the ECE 475 MIPS cross compiler.

 

Sinewave Generator:

 

#Repeatedly load the next value of the sine function into memory address 0.

Label:      li $1,0x80

                sw $1, 0($0)

                li $1, 0xb1

                 sw $1, 0($0)

                li $1,0xda

                sw $1,  0($0)

                li $1,0xf6

                 sw $1, 0($0)   

                li $1, 0xff

                sw $1, 0($0)

                li $1, 0xf6

                 sw $1, 0($0)

                li $1, 0xda

                 sw $1, 0($0)

                li $1, 0xb1

                 sw $1, 0($0)

                li $1, 0x80

                 sw $1, 0($0)

                li $1, 0x4f

                 sw $1, 0($0)

                li $1, 0x26

                 sw $1, 0($0)

                li $1, 0x0a

                 sw $1, 0($0)

                li $1, 0x00

                 sw $1, 0($0)

                li $1, 0x0a

                 sw $1, 0($0)

                li $1, 0x26

                 sw $1, 0($0)

                li $1, 0x4f

                sw $1, 0($0)

                j Label 

 

Toggle Mem[0]:

 

#Toggle memory location 0 between 0 and 1

 

Label:             li $2, 0

                        sw $2, 0($0)

                        li $2, 1

                        sw $2, 0($0)

                        j Label

 

 

The results of the simulation are shown below. The plots are taken directly form the excel file generated by the simulator, where the node names agree with the definitions in the dump statements. The plot on the left shows the output of the DAC and the output of the Op Amp vs. time. The plot on the right shows the voltage on the second cpu’s port as a function of time. The microcontrollers spend the initial 40 cycles warming up the L1 cache.  After this point, the sine values are stable. The second cpu is also affected by the cache miss in the same way.

 

 

Figure 1

 

Figure 2

The results of the digital simulation are shown below. The bottom 3 rows show the output of the logic gates, the values of the emory location for CPU1 and CPU2, respectively.

Figure 3

 

 

As expected CPU1 sets MEM[0] to the sine values while the second CPU toggles its MEM[0].

           

Netlist Files:

The only update to the netlist files in this version of the simulator is the syntax of the PORT declarations. PORT declarations must now have the name of the corresponding CPU as their first argument since there can be more than one processor running simulataneously. Hence, a typical PORT declaration would look like:

 

PORT cpu_name node_number IO_address bit_number.

 

Other than this difference, the format of the Netlist file remained unchanged.

 

Mask Files:

In order for the ADL simulator to correctly distinguish between instructions, a mask file that describes the opcodes of the instructions is necessary. As different ISA’s encode instructions differently, the mask file consists of a list of entries that gives the name of the instruction, a bitmask, a key and an instruction format. These fields are separated by semicolons:

 

Instruction_name : bit_mask : key : instruction_format

 

At runtime, the ADL simulator performs a logical AND between the current instruction and a the bit mask. If the result is equal to the key, the getArgs() function is called with the given instruction format and the corresponding instruction is executed with the resulting arguments. Hence, the bitmask/key pair can be used to distinguish between instructions in any ISA.

 

 

MCU Models:

In order to specify a processor model, the user must write a java file that extends ADLSimulator. The key features of these models are listed below while an example is provided in the listing section:

 

Instructions:

All instructions are represented by methods that have the following signature:

 

public void instruction_name( Integer[] args){}

 

The args[] array is an array of arguments that will be extracted from the instruction based on the corresponding instruction format. Within the body of the method, the uiser is free to use any features of the simulator as well as any general java constructs.

 

Arguments:

In order for the arguments of the instructions to be extracted properly, the user must provide the following function:

 

public Integer[] getArgs(String format, long Instruction){}

 

Once the current instruction is compared against the entries in the mask file, the corresponding format string will be passed to getArgs with the instruction.

GetArgs must extract the arguments from the instruction and return them in an array.

 

PC:

PC is a reserved key word and represents the program counter. The user can specify how the instruction changes the PC by peforming operations on this

Identifier (eg. PC++; will increment the PC for the next iteration of the simulation).

 

LATENCY:

The latency of every instruction is 1 cycle by default. However, the user can change this by using the LATENCY keyword. For instance, using

“LATENCY = 32;” within the body of an instruction will cause the instruction to have a 32 cycle latency. Instructions that access the memory hierarcy

will have a variable latency based on the cache hits and misses and the latencies will be calculated by simulator at runtime.

 

Register File:

The keyword “R” is used to represent the register file. The register file is an array of integers whose length must be specified by the used.

 

Data Memory:

The data memory can be specified either as a single main memory or as a memory hierarchy. If there are no caches, then the keyword DMEM must be used to access data memory. DMEM is an array of integers whose length must be specified by the used.

If a memory hierarchy with caches is present, the DMEMH keyword will represent the hierarchy. DMEMH.putWord(int address, long data) can be used for stores, and DMEMH.getWord(int address) can be used for loads.

Caches:

The constructor for instantiating a new cache has the following signature. The user can call this constructor to instantiate a cache in the constructor for the MCU model.

 

public Cache(int blockSize, int Associativity, int Replacement, int NumLines, Mem Parent,int Latency){}

 

The first 4 arguments are regular cache parameters. Parent is either another cache or MainMem that is immediatelyabove this cache in the hierarchy.

Latency is the access time of the cache.

 

Main Memory:

The constructor for the main memory is shown below

 

public MainMem(int accessTime){}

 

The main memory must be the topmost node of every memory hierarchy for correct operation.

 

Other Methods:

Aside from these features, the following methods are provided as abstractions to the user:

 

public void beforeInst(){} : will be called before every instruction

public void afterInst(){}    : will be called after every instruction

public void always(){}      : will be called every cycle

public void init(){}            : will be called before the simulation starts, after the CPU model is loaded with instructions

public void finish(){}        : will be called after the simulation ends

Improvements:

Given enough time, the simulator could be optimized by performing sparse matrix techniques in analog simulation. This would significantly reduce the simulation time of mixed signal systems with a high number of analog components.

Listing:

Below is a listing of the code that can be compiled with any standard Java compiler.

ADLSimulator

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2003</p>

 * <p>Company: </p>

 * @author not attributable

 * @version 1.0

 */

 

public class ADLSimulator {

  //name of the processor

  public String name;

  //Number of cycles passed so far

  public long cycleNum;

  //Pipeline structure

  public String PIPELINE;

  //DMEM size

  public int dmemSize;

  //RF size

  public int regfileSize;

  //Register File

  public int[] R;

  //PC

  public int PC;

  //Latency of the instruction

  public int LATENCY;

  //Data memory

  public long DMEM[];

  //Fetcher

   public fetcher f;

   //Memory Hierarchy

   public Mem DMEMH;

  //Constructor

  public ADLSimulator(String instFile, String maskFile,int dmemSize,int regfileSize,String PIPELINE){

    DMEMH = new Mem();

    cycleNum = 0;

    PC = 0;

    LATENCY = 1;

    f = new fetcher(instFile, maskFile);

    DMEM = new long[dmemSize];

   // DMEM = Mem.vals;

    R = new int[regfileSize];

  }

  //Constructor

  public ADLSimulator(){

  }

  //Template for getArgs

   public Integer[] getArgs(String format, long instruction){

     return null;

   }

  //Step the CPU

  public void run() {

    LATENCY = 1;

    beforeInst();

    f.run(PC,this);

    cycleNum = cycleNum + LATENCY;

    afterInst();

  }

  //Initialization

  public void init(){}

  //Last call

  public void finish(){}

  //Called once before every instruction

  public void beforeInst(){}

  //Called once after every instruction

  public void afterInst(){}

  public boolean getBit(byte b, int bitNum) {

    byte temp = 1;

    return ( (b & (temp << bitNum)) != 0);

  }

 

  public boolean getBit(int i, int bitNum) {

    int temp = 1;

    return ( (i & (temp << bitNum)) != 0);

  }

 

  public boolean getBit(long i, int bitNum) {

   int temp = 1;

   return ( (i & (temp << bitNum)) != 0);

 }

 

 

 

}

 

Cache

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2003</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

 

 //Memory Hierarchy simulation class

public class Cache extends Mem{

 

   //Statistics

   public long numMisses;

   public long numHits;

   //Cache parameters

   int byteOffsetLength;

   int associativity;

   int replacement;

   int numLines;

   int numLinesLog2;

   //Upper level of Mem hierarchy

   Mem parent;

   //Tags and data

   long[][] tags;

   int fifo[][];

   public int log2(int powerOf2){

     int i = 0;

     for(int j=1; j != 0; j = j <<1){

       if((powerOf2 & j) != 0)

         break;

       i++;

     }

     return i;

   }

   public Cache(int blockSize, int Associativity, int Replacement, int NumLines, Mem Parent,int Latency){

     numMisses = 0;

     numHits = 0;

     tags = new long[NumLines][Associativity];

     fifo = new int[NumLines][Associativity];

     for(int i = 0; i < tags.length; i++){

       for(int j = 0; j < tags[0].length; j++){

         tags[i][j] = -1;

         fifo[i][j] = j;

       }

     }

     byteOffsetLength = log2(blockSize);

     associativity = Associativity;

     replacement = Replacement;

     numLines = NumLines;

     parent = Parent;

     latency = Latency;

     numLinesLog2 = log2(NumLines);

 

   }

   public long getWord(int address){

     totalLatency = totalLatency + latency;

     long result = vals[address];

     int index = (int)((address >>> byteOffsetLength) & (numLines - 1));

     long tag = address >>> (byteOffsetLength + numLinesLog2);

     for(int i = 0; i < tags[0].length; i++){

       if(tags[index][i] == tag){

         numHits++;

         return vals[address];

       }

     }

     numMisses++;

     tags[index][getSet(index)] = tag;

     long temp = parent.getWord(address);

     return result;

   }

   public void putWord(int address, long data){

     vals[address] = data;

     totalLatency = totalLatency + latency;

     int index = (int)((address >>> byteOffsetLength) & (numLines - 1));

     long tag = address >>> (byteOffsetLength + numLinesLog2);

     for(int i = 0; i < tags[0].length; i++){

       if(tags[index][i] == tag){

         numHits++;

         return;

       }

     }

     numMisses++;

     tags[index][getSet(index)] = tag;

     parent.putWord(address,data);

   }

   public int getSet(int index){

     if(replacement == RANDOM){

       return (int)Math.random()*associativity;

     }

     else if(replacement == FIFO){

       fifo[index][fifo[index].length-1] = fifo[index][0];

       for(int i = 0; i < fifo[index].length - 1; i++){

         fifo[index][i] = fifo[index][i+1];

       }

       return fifo[index][0];

     }

     else return 0;

   }

   public long getNumHits(){

     return numHits;

   }

   public long getNumMisses(){

     return numMisses;

   }

 

}

 

Compiler

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2002</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

 

public class Compiler {

  final int G = 0;

  final int VSRC = 1;

  final int CSRC = 2;

  final int CCVS = 3;

  final int CCCS = 4;

  final int VCVS = 5;

  final int VCCS = 6;

  final int OpAmp = 7;

  final int GI = 8;

  final int D = 9;

  final int CAC = 10;

  final int CDC = 11;

  final int VAC = 12;

  double x[];

  double z[];

  //Compile the circuit & formulate the matrixsys

  public double[][] Compile(Element[] e, int noOfNodes) {

    Element[] element = new Element[e.length];

    for(int i = 0; i< element.length; i++){

     //System.out.println(e[i].TYPE+" "+e[i].nj+" "+e[i].nk+" "+e[i].np+" "+e[i].nq+" "+e[i].p+" "+e[i].pnl0

       //                       +" "+e[i].pnl1+" "+e[i].pnl2);

      element[i] = new Element(e[i].TYPE,e[i].nj,e[i].nk,e[i].np,e[i].nq,e[i].p,e[i].pnl0,e[i].pnl1,e[i].pnl2);

      element[i].MCU = e[i].MCU;

    }

   // System.out.println("*******************************************************************");

    //Find the number of additional current variables needed

    // & generate additional current variables for dependent sources

    int m = 0;

    int iTemp = 1;

    for(int i = 0; i < element.length ; i++){

      if((element[i].TYPE == VSRC) |

         (element[i].TYPE == VAC) |

         (element[i].TYPE == VCVS) |

         (element[i].TYPE == GI)   |

         (element[i].TYPE == CCCS) |

         (element[i].TYPE == OpAmp)){

         m++;

         element[i].iVar0 = iTemp;

         iTemp++;

         }

      if(element[i].TYPE == CCVS){

        m = m+2;

        element[i].iVar0 = iTemp;

        element[i].iVar1 = iTemp + 1;

        iTemp = iTemp + 2;

      }

 

    }

    //Initialize the matrix & vectors

    double A[][] = new double[noOfNodes+m][noOfNodes+m];

    x = new double[noOfNodes+m];

    z = new double[noOfNodes+m];

    //Process the element list

    for(int i = 0; i < element.length ; i++){

      element[i].nj--;

      element[i].nk--;

      element[i].np--;

      element[i].nq--;

      switch(element[i].TYPE){

        //Conductance

        case G:

        if(element[i].nj>-1)

          A[element[i].nj][element[i].nj] = A[element[i].nj][element[i].nj] + element[i].p;

        if(element[i].nk>-1)

          A[element[i].nk][element[i].nk] = A[element[i].nk][element[i].nk] + element[i].p;

        if((element[i].nj>-1)&&(element[i].nk>-1)){

          A[element[i].nj][element[i].nk] = A[element[i].nj][element[i].nk] - element[i].p;

          A[element[i].nk][element[i].nj] = A[element[i].nk][element[i].nj] - element[i].p;

        }

        break;

        //Current Source

        case CSRC:

        if(element[i].nj>-1)

          z[element[i].nj] = z[element[i].nj] + element[i].p;

        if(element[i].nk>-1)

          z[element[i].nk] = z[element[i].nk] - element[i].p;

        break;

        //Voltage Source

        case VSRC:

        if(element[i].nk>-1)

          A[element[i].nk][element[i].iVar0 + noOfNodes - 1]++;

        if(element[i].nj>-1)

          A[element[i].nj][element[i].iVar0 + noOfNodes - 1]--;

        if(element[i].nk>-1)

          A[element[i].iVar0 + noOfNodes -1][element[i].nk]++;

        if(element[i].nj>-1)

          A[element[i].iVar0 + noOfNodes -1][element[i].nj]--;

          z[element[i].iVar0 + noOfNodes -1] = element[i].p;

        break;

        //Current Controlled Voltage Source

        case CCVS:

        if(element[i].nk>-1)

          A[element[i].nk][element[i].iVar0 +noOfNodes -1]++;

        if(element[i].nj>-1)

          A[element[i].nj][element[i].iVar0+noOfNodes -1]--;

        if(element[i].nk>-1)

          A[element[i].iVar1 +noOfNodes-1][element[i].nk]++;

        if(element[i].nj>-1)

          A[element[i].iVar1 +noOfNodes-1][element[i].nj]--;

          A[element[i].iVar1 +noOfNodes-1][element[i].iVar1 +noOfNodes-1] =

          A[element[i].iVar1 +noOfNodes-1][element[i].iVar1 +noOfNodes-1] + element[i].p;

        break;

        //Voltage Controlled Voltage Source

        case VCVS:

        if(element[i].nk>-1)

          A[element[i].nk][element[i].iVar0 +noOfNodes -1]++;

        if(element[i].nj>-1)

          A[element[i].nj][element[i].iVar0+noOfNodes -1]--;

        if(element[i].nk>-1)

          A[element[i].iVar0 +noOfNodes-1][element[i].nk]++;

        if(element[i].nj>-1)

          A[element[i].iVar0 +noOfNodes-1][element[i].nj]--;

        if(element[i].np>-1)

          A[element[i].iVar0 +noOfNodes-1][element[i].np]= A[element[i].iVar0 +noOfNodes-1][element[i].np]-element[i].p;

        if(element[i].nq>-1)

          A[element[i].iVar0 +noOfNodes-1][element[i].nq]= A[element[i].iVar0 +noOfNodes-1][element[i].nq]+element[i].p;

        break;

        //Current Controlled Current Source

        case CCCS:

        if(element[i].nk>-1)

          A[element[i].nk][element[i].iVar0+noOfNodes -1] = A[element[i].nk][element[i].iVar0+noOfNodes -1] +element[i].p;

        if(element[i].nj>-1)

          A[element[i].nj][element[i].iVar0+noOfNodes -1] = A[element[i].nj][element[i].iVar0+noOfNodes -1] -element[i].p;

        break;

        //Voltage Controlled Current Source

        case VCCS:

        if((element[i].nk>-1)&&(element[i].np>-1))

          A[element[i].nk][element[i].np]=A[element[i].nk][element[i].np]+element[i].p;

         if((element[i].nk>-1)&&(element[i].nq>-1))

          A[element[i].nk][element[i].nq]=A[element[i].nk][element[i].nq]-element[i].p;

         if((element[i].nj>-1)&&(element[i].np>-1))

          A[element[i].nj][element[i].np]=A[element[i].nj][element[i].np]-element[i].p;

         if((element[i].nj>-1)&&(element[i].nq>-1))

          A[element[i].nj][element[i].nq]=A[element[i].nj][element[i].nq]+element[i].p;

        break;

        //Ideal Op Amp

        case OpAmp:

         if(element[i].np>-1)

          A[element[i].np][element[i].iVar0+noOfNodes-1]++;

         if(element[i].nk>-1)

          A[element[i].iVar0+noOfNodes-1][element[i].nk]++;

         if(element[i].nj>-1)

          A[element[i].iVar0+noOfNodes-1][element[i].nj]--;

        break;

        //Conductance with current as an output variable

        case GI:

         if(element[i].nk>-1)

          A[element[i].nk][element[i].iVar0+noOfNodes-1]++;

        if(element[i].nj>-1)

          A[element[i].nj][element[i].iVar0+noOfNodes-1]--;

        if(element[i].nk>-1)

          A[element[i].iVar0+noOfNodes-1][element[i].nk]=A[element[i].iVar0+noOfNodes-1][element[i].nk]+element[i].p;

        if(element[i].nj>-1)

          A[element[i].iVar0+noOfNodes-1][element[i].nj]=A[element[i].iVar0+noOfNodes-1][element[i].nj]-element[i].p;

          A[element[i].iVar0+noOfNodes-1][element[i].iVar0+noOfNodes-1]--;

        break;

        //Diode

        case D:

        if(element[i].nj>-1){

          A[element[i].nj][element[i].nj] = A[element[i].nj][element[i].nj] + element[i].p;

          z[element[i].nj]=z[element[i].nj]+element[i].pnl0;

        }

        if(element[i].nk>-1){

          A[element[i].nk][element[i].nk] = A[element[i].nk][element[i].nk] + element[i].p;

          z[element[i].nk]=z[element[i].nk]-element[i].pnl0;

        }

        if((element[i].nj>-1)&&(element[i].nk>-1)){

          A[element[i].nj][element[i].nk] = A[element[i].nj][element[i].nk] - element[i].p;

          A[element[i].nk][element[i].nj] = A[element[i].nk][element[i].nj] - element[i].p;

        }

        break;

      //Capacitor

      case CAC:

      if(element[i].nj>-1){

          A[element[i].nj][element[i].nj] = A[element[i].nj][element[i].nj] + element[i].p;

          z[element[i].nj]=z[element[i].nj]-element[i].pnl0;

        }

        if(element[i].nk>-1){

          A[element[i].nk][element[i].nk] = A[element[i].nk][element[i].nk] + element[i].p;

          z[element[i].nk]=z[element[i].nk]+element[i].pnl0;

        }

        if((element[i].nj>-1)&&(element[i].nk>-1)){

          A[element[i].nj][element[i].nk] = A[element[i].nj][element[i].nk] - element[i].p;

          A[element[i].nk][element[i].nj] = A[element[i].nk][element[i].nj] - element[i].p;

        }

      break;

 

    //VAC

    case VAC:

        if(element[i].nk>-1)

          A[element[i].nk][element[i].iVar0 + noOfNodes - 1]++;

        if(element[i].nj>-1)

          A[element[i].nj][element[i].iVar0 + noOfNodes - 1]--;

        if(element[i].nk>-1)

          A[element[i].iVar0 + noOfNodes -1][element[i].nk]++;

        if(element[i].nj>-1)

          A[element[i].iVar0 + noOfNodes -1][element[i].nj]--;

          z[element[i].iVar0 + noOfNodes -1] = element[i].p;

        break;

      }

    }

 

    return A;

  }

 

 

}

 

Element

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2002</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

 

public class Element {

  //Corresponding MCU for PORTS

  String MCU ;

  //Type of the circuit element

  public int TYPE = 0;

  //Nodes connected to the element

  public int nj, nk, np, nq;

  //Parameter related to the element

  public double p, pnl0, pnl1,pnl2;

  //Additional current variables

  public int iVar0, iVar1;

  //Initizalize an element from given nodes and a parameter

  public Element(int type, int Nj, int Nk, int Np, int Nq, double p0, double pn0,double pn1, double pn2) {

    TYPE = type;

    nj = Nj;

    nk = Nk;

    np = Np;

    nq = Nq;

    p = p0;

    pnl0 = pn0;

    pnl1 = pn1;

    pnl2 = pn2;

  }

}

 

Fetcher

 

package adlsim;

import java.util.*;

import java.io.*;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2003</p>

 * <p>Company: </p>

 * @author not attributable

 * @version 1.0

 */

 

public class fetcher {

  long[] Mem;

  long[] masks;

 // Integer[] array;

 // Integer single;

 // Object[] args = {single,array};

  Hashtable functions;

  Hashtable formats;

  FileReader f;

  BufferedReader br;

 

  public fetcher(String instFile, String maskFile) {

     functions = new Hashtable();

     formats = new Hashtable();

     try{

 

        // Create a new file reader

        // connected to maskFile

        FileReader f = new FileReader(maskFile);

        BufferedReader br = new BufferedReader(f);

 

        // Create a new file reader

        // connected to instFile

        FileReader fi = new FileReader(instFile);

        BufferedReader bri = new BufferedReader(fi);

 

        //Vector for decoding the instruction file

        Vector instrs = new Vector();

 

        //Load the instructions

        String str = bri.readLine();

        String[] strArray = str.split(" ");

        String str0 = strArray[1].substring(0,10);

        String str1 = "0x"+strArray[1].substring(10,18);

        //System.out.println(str0+ " " + str1);

        while(str!=null){

          strArray = str.split(" ");

          str0 = strArray[1].substring(0,10);

          str1 = "0x"+strArray[1].substring(10,18);

          instrs.add(str0);

          instrs.add(str1);

          str = bri.readLine();

 

 

        }

 

        Mem = new long[instrs.size()];

 

        for(int i = 0; i<Mem.length; i++){

          Mem[i] = Long.decode((String)instrs.get(i)).longValue();

        }

 

 

        //Vectors for decoding the mask file

        Vector fun = new Vector();

        Vector msk = new Vector();

        Vector key = new Vector();

        Vector format = new Vector();

 

        //Walk through the msk file and set parameters

        String s = br.readLine();

        while(s != null){

          String line[] = s.split(":");

          fun.add(line[0]);

          msk.add(line[1]);

          key.add(line[2]);

          format.add(line[3]);

          s = br.readLine();

        }

        //Insert the masks

        masks = new long[msk.size()];

        for(int i = 0 ; i < masks.length; i++){

          masks[i] = Long.decode((String)msk.get(i)).longValue();

        }

        //Insert the functions

        for(int i = 0; i < key.size(); i++){

          functions.put(Long.decode((String)key.get(i)),fun.get(i));

        }

        //Bind the formats

        for(int i = 0; i < format.size(); i++){

          formats.put(Long.decode((String)key.get(i)),format.get(i));

        }

      }

      catch(Exception exc){System.out.println("Error in mask file or hex file.");}

  }

  public void runAlways(){

 

  }

 

  public void runInit(){

 

  }

 

  public void runFini(){

 

  }

 

 

  //Run the instruction at the given index with the given CPU state

  public void run(int index, ADLSimulator mcu){

    Integer[] temp = new Integer[1];

    Integer[] args;

    Class[] types = {temp.getClass()};

    String funName = null;

    String formatName = null;

    long instruction = Mem[index];

 

    //Get the correct format name

 

    for(int i = 0; i < masks.length; i++){

      formatName = (String)formats.get((new Long((int)masks[i] & instruction)));

      if(formatName != null)

        break;

    }

    //Get the arguments

    args = mcu.getArgs(formatName,instruction);

    //Get the correct function name

    for(int i = 0; i < masks.length; i++){

      funName = (String)functions.get((new Long((int)masks[i] & instruction)));

      if(funName != null)

        break;

    }

 

 

    try{

      Object[] wrapper = {args};

      mcu.getClass().getMethod(funName,types).invoke(mcu,wrapper);

    }

    catch(Exception e){

      System.out.println("Instruction description for \"" +funName+ "\" not found in MCU.java");

 

 

    }

  }

}

 

HexReader

package adlsim;

 

 

 

/**

 * <p>Title: AVRSim</p>

 * <p>Description: Mixed Signal AVR Simulator</p>

 * <p>Copyright: Copyright (c) 2002</p>

 * <p>Company: Cornell University</p>

 * @author unascribed

 * @version 1.0

 */

 

import java.io.*;

 

public class HexReader {

 

  FileReader f; // declare a file reader object

  private int recordLength = 0;

  private String recordLengthS;

  private int address = 0;

  private String addressS;

  private char[] buffer = new char[100];

  private int index;

  private int dataIndex;

 

 

 

  public void loadMEM(String S, short[] Mem){

 

 

 

  try{

 

    // Create a new file reader

    // connected to S

    f = new FileReader(S);

    BufferedReader br = new BufferedReader(f);

    index = 0;

    dataIndex = 9;

    char[] temp0 = (br.readLine()).toCharArray();

    int countMod4 = 0;

    while(index<9){

      buffer[index] = temp0[index];

      index++;

    }

    while(index<temp0.length-2){

      if(countMod4 < 2)

        buffer[index+2] = temp0[index];

      else

        buffer[index-2] = temp0[index];

      index++;

      countMod4 = (countMod4 + 1)%4;

    }

 

 

 

 

    while((buffer[7] != '0') | (buffer[8] != '1')){

    //System.out.println("temp0:"+String.valueOf(temp0));

    //System.out.println("temp0.length=" +temp0.length);

     /// System.out.println("Buffer:"+String.valueOf(buffer));

      index = 0;

      dataIndex = 9;

 

 

      recordLengthS = "0x" +String.copyValueOf(buffer,1,2);

      addressS = "0x"+String.copyValueOf(buffer,3,4);

      recordLength = 2*Integer.decode(recordLengthS).intValue();

      address = Integer.decode(addressS).intValue()/2;

 

 

      while(recordLength > 0){

 

 

 

        Mem[address] = (short)(Integer.decode("0x"+String.copyValueOf(buffer,dataIndex,4)).intValue());

        //System.out.println("MEM["+address+"]="+String.copyValueOf(buffer,dataIndex,4));

        dataIndex = dataIndex +4;

        address++;

 

        recordLength = recordLength - 4;

      }

 

      char[] temp = (br.readLine()).toCharArray();

 

      index = 0;

      countMod4 = 0;

 

      while(index<9){

        buffer[index] = temp[index];

        index++;

      }

      while(index<temp.length-2){

        if(countMod4 < 2)

          buffer[index+2] = temp[index];

        else

          buffer[index-2] = temp[index];

        index++;

        countMod4 = (countMod4 + 1)%4;

      }

  }

}

  catch (Exception e){

 

    System.err.println ("Error reading file");

 

 

  }

  }

  public static void main(String[] args){

    String h = "hello";

    char[] hello = h.toCharArray();

    for(int i = 0; i < hello.length; i++){

      System.out.println((int)hello[i]);

    }

    ADLSimulator MCU = new MCU("INST.txt","MASK.txt","cpu1");

    ADLSimulator MCU2 = new MCU("INST2.txt", "MASK.txt","cpu2");

    ADLSimulator MCUs[] = {MCU,MCU2};

    Parser p = new Parser();

    Element[] e = p.Parse("itestsinewave.net");

    Compiler C = new Compiler();

    Solver S = new Solver();

    double[][]A = C.Compile(e,19);

   // System.out.println("TIME IS:" + System.currentTimeMillis());

    Logic logic = new Logic(22,p.el);

    double[] x = S.SolveAC(A,C.z,1,1,10000,e,MCUs,

                            p.ID,p.dataAddr,p.IDIndex,p.mcuName,

                            p.IDAnalog,p.nodeNum,p.IDIndexAnalog,

                            p.IDLogic,p.nodeNumLogic,p.IDIndexLogic,logic);

   // System.out.println("TIME IS:" + System.currentTimeMillis());

 

}

}

 

Logic:

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2002</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

 

public class Logic {

  final int AND = 1;

  final int OR = 2;

  final int NOT = 3;

  final int DFF = 4;

  public boolean oldNodeVals[];

  public boolean[] externalInputs;

  public LogicElement[] le;

  public Logic(int noOfNodes, LogicElement[] Le){

    oldNodeVals = new boolean[noOfNodes];

    le = new LogicElement[Le.length];

    for(int i =0;i<Le.length; i++){

      le[i] = Le[i];

    }

    externalInputs = new boolean[noOfNodes];

    for(int i=0; i<externalInputs.length; i++){

      externalInputs[i]=true;

    }

    for(int i=0; i<le.length; i++){

      //System.out.println("in1:"+le[i].in1);

        //System.out.println("in2:"+le[i].in2);

      //  System.out.println("out:"+le[i].out);

      for(int j=0;j<le.length; j++){

        if(le[i].in1==le[j].out)

          externalInputs[le[i].in1]=false;

        if(le[i].in2==le[j].out)

          externalInputs[le[i].in2]=false;

        externalInputs[le[j].out]=false;

      }

    }

  }

  public boolean[] SolveLogic(boolean[] nodeVals){

    boolean updatedNodes[] = new boolean[nodeVals.length];

    for(int i = 0; i<nodeVals.length; i++){

      updatedNodes[i] = (oldNodeVals[i]!=nodeVals[i]);

    }

    boolean Done = false;

    while(!Done){

      for(int upIndex = 0 ; upIndex < updatedNodes.length; upIndex++){

        if(updatedNodes[upIndex]){

          updatedNodes[upIndex] = false;

          for(int leIndex = 0; leIndex<le.length; leIndex++){

            if((le[leIndex].in1 == upIndex)|(le[leIndex].in2 == upIndex)){

              if(le[leIndex].TYPE == AND){

                updatedNodes[le[leIndex].out] =

                ((nodeVals[le[leIndex].in1]&nodeVals[le[leIndex].in2])== nodeVals[le[leIndex].out]);

                 nodeVals[le[leIndex].out] = nodeVals[le[leIndex].in1]&nodeVals[le[leIndex].in2];

              }

              else  if(le[leIndex].TYPE == OR){

                updatedNodes[le[leIndex].out] =

                (nodeVals[le[leIndex].in1]|nodeVals[le[leIndex].in2]==nodeVals[le[leIndex].out]);

                 nodeVals[le[leIndex].out] = nodeVals[le[leIndex].in1]|nodeVals[le[leIndex].in2];

              }

               else  if(le[leIndex].TYPE == DFF){

                updatedNodes[le[leIndex].out] =

                (nodeVals[le[leIndex].out]==(nodeVals[le[leIndex].in1]&(le[leIndex].in2==upIndex)&

                nodeVals[le[leIndex].in2]));

                nodeVals[le[leIndex].out] =

                nodeVals[le[leIndex].in1]&(le[leIndex].in2 == upIndex)&nodeVals[le[leIndex].in2];

              }

            }

          }

        }

      }

      Done = true;

      for(int i=0; i < updatedNodes.length; i++){

        if(updatedNodes[i])

          Done = false;

      }

    }

    for(int i = 0; i<nodeVals.length; i++){

      oldNodeVals[i]=nodeVals[i];

    }

    return nodeVals;

  }

 

}

 

LogicElement:

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2002</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

 

public class LogicElement {

  public int TYPE = 0;

  public int in1 = 0;

  public int in2 = 0;

  public int out = 0;

  public LogicElement(int Type, int In1, int In2, int Out) {

    TYPE= Type;

    in1 = In1;

    in2 = In2;

    out = Out;

  }

}

 

MainMem:

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2003</p>

 * <p>Company: </p>

 * @author not attributable

 * @version 1.0

 */

 

public class MainMem extends Mem{

  public MainMem(int accessTime) {

    latency = accessTime;

  }

 

  public long getWord(int address){

    //System.out.println("L1 Miss");

    totalLatency = totalLatency + latency;

     return vals[address];

 

  }

  public void putWord(int address, long data){

    vals[address] = data;

    totalLatency = totalLatency + latency;

  }

 

 

}

MCU:

package adlsim;

 

import java.util.*;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2003</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

 

public class MCU extends ADLSimulator {

  int HI, LO;

  int target;

  boolean delaySlot, branch;

  //This constructor must be present in the MCU file

  public MCU(String instFile, String maskFile, String cpuName) {

    super(instFile, maskFile, 100, 32, "IF|RD|EX|MEM|WB");

    name = cpuName;

    //Initialize memory hierarchy

    MainMem m = new MainMem(40);

    Cache L1 = new Cache(32, 2, Mem.RANDOM, 512, m, 1);

    DMEMH = L1;

    //This line must be present when modeling caches

    DMEM = DMEMH.vals;

  }

 

  //Extract the arguments from the instruction word based on the instruction format

  public Integer[] getArgs(String format, long instruction) {

    Integer[] args = new Integer[3];

    //I-type

    if (format.equals("I")) {

      args[0] = new Integer( (int) ( (instruction >>> 21) & 0x0000001f));

      args[1] = new Integer( (int) ( (instruction >>> 16) & 0x0000001f));

      args[2] = new Integer( (int) (instruction & 0x0000ffff));

      if ( (args[2].intValue() & 0x00008000) != 0) {

        args[2] = new Integer(args[2].intValue() | 0xffff0000);

      }

    }

    //J-type

    else if (format.equals("J")) {

      args = new Integer[1];

      args[0] = new Integer( (int) (instruction & 0x03ffffff));

    }

    //R-type

    else if (format.equals("R")) {

      args = new Integer[4];

      args[0] = new Integer( (int) ( (instruction >>> 21) & 0x0000001f));

      args[1] = new Integer( (int) ( (instruction >>> 16) & 0x0000001f));

      args[2] = new Integer( (int) ( (instruction >>> 11) & 0x0000001f));

      args[3] = new Integer( (int) ( (instruction >>> 6) & 0x0000001f));

    }

 

    return args;

  }

 

  /******************** INSTRUCTIONS ************************************/

  //Add

  public void add(Integer[] args) {

    R[args[2].intValue()] = R[args[0].intValue()] + R[args[1].intValue()];

    PC++;

  }

 

  //Addu

  public void addu(Integer[] args) {

    R[args[2].intValue()] = R[args[0].intValue()] + R[args[1].intValue()];

    PC++;

  }

 

  //And

  public void and(Integer[] args) {

    R[args[2].intValue()] = R[args[0].intValue()] & R[args[1].intValue()];

    PC++;

  }

 

  //Div

  public void div(Integer[] args) {

    LO = R[args[0].intValue()] / R[args[1].intValue()];

    HI = R[args[0].intValue()] % R[args[1].intValue()];

    PC++;

    LATENCY = 32;

  }

 

  //Divu

  public void divu(Integer[] args) {

    LO = R[args[0].intValue()] / R[args[1].intValue()];

    HI = R[args[0].intValue()] % R[args[1].intValue()];

    PC++;

    LATENCY = 32;

  }

 

  //Or

  public void or(Integer[] args) {

    R[args[2].intValue()] = R[args[0].intValue()] | R[args[1].intValue()];

    PC++;

  }

 

  //Nor

  public void nor(Integer[] args) {

    R[args[2].intValue()] = ~ (R[args[0].intValue()] | R[args[1].intValue()]);

    PC++;

  }

 

  //Sll

  public void sll(Integer[] args) {

    R[args[2].intValue()] = R[args[1].intValue()] << R[args[3].intValue()];

    PC++;

  }

 

  //Sllv

  public void sllv(Integer[] args) {

    R[args[2].intValue()] = R[args[1].intValue()] << R[args[0].intValue()];

    PC++;

  }

 

  //Addiu

  public void addiu(Integer[] args) {

    R[args[1].intValue()] = R[args[0].intValue()] + args[2].intValue();

    PC++;

  }

 

  //Lw

  public void lw(Integer[] args) {

    DMEMH.putWord(R[args[0].intValue()] + args[2].intValue(),

                  R[args[1].intValue()]);

    PC++;

  }

 

  //Sw

  public void sw(Integer[] args) {

    DMEMH.totalLatency = 0;

    DMEMH.putWord(args[0].intValue() + args[2].intValue(), R[args[1].intValue()]);

    LATENCY = DMEMH.totalLatency;

    PC++;

  }

 

  //J

  public void j(Integer[] args) {

    target = args[0].intValue();

    branch = true;

    PC++;

  }

 

  //Beq

  public void beq(Integer[] args) {

    target = PC + 1 + args[2].intValue();

    if (R[args[0].intValue()] == R[args[1].intValue()]) {

      branch = true;

    }

    PC++;

  }

 

  //Bne

  public void bne(Integer[] args) {

    target = PC + 1 + args[2].intValue();

    if (R[args[0].intValue()] != R[args[1].intValue()]) {

      branch = true;

    }

    PC++;

  }

 

  //Bgez

  public void bgez(Integer[] args) {

    target = PC + 1 + args[2].intValue();

    if (R[args[0].intValue()] >= 0) {

      branch = true;

    }

    PC++;

  }

 

  //Bgtz

  public void bgtz(Integer[] args) {

    target = PC + 1 + args[2].intValue();

    if (R[args[0].intValue()] > 0) {

      branch = true;

    }

    PC++;

  }

 

  //Blez

  public void blez(Integer[] args) {

    target = PC + 1 + args[2].intValue();

    if (R[args[0].intValue()] <= 0) {

      branch = true;

    }

    PC++;

  }

 

  //Bltz

  public void bltz(Integer[] args) {

    target = PC + 1 + args[2].intValue();

    if (R[args[0].intValue()] < 0) {

      branch = true;

    }

    PC++;

  }

 

  //Ori

  public void ori(Integer[] args) {

    R[args[1].intValue()] = R[args[0].intValue()] | R[args[2].intValue()];

    PC++;

  }

 

  //Addi

  public void addi(Integer[] args) {

    R[args[1].intValue()] = R[args[0].intValue()] + R[args[2].intValue()];

    PC++;

  }

 

  //Andi

  public void andi(Integer[] args) {

    R[args[1].intValue()] = R[args[0].intValue()] & R[args[2].intValue()];

    PC++;

  }

 

  //Xori

  public void xori(Integer[] args) {

    R[args[1].intValue()] = R[args[0].intValue()] ^ R[args[2].intValue()];

    PC++;

  }

 

  //Slti

  public void slti(Integer[] args) {

    R[args[1].intValue()] = (R[args[0].intValue()] < R[args[2].intValue()]) ? 1 :

        0;

    PC++;

  }

 

  //Sub

  public void sub(Integer[] args) {

    R[args[2].intValue()] = R[args[0].intValue()] - R[args[1].intValue()];

    PC++;

  }

 

  //Xor

  public void xor(Integer[] args) {

    R[args[2].intValue()] = R[args[0].intValue()] ^ R[args[1].intValue()];

    PC++;

  }

 

  //Mult

  public void mult(Integer[] args) {

    long product = R[args[0].intValue()] * R[args[1].intValue()];

    HI = (int) (product >>> 32);

    LO = (int) (product & 0x00000000ffffffff);

    PC = PC + 32;

  }

 

  //Mflo

  public void mflo(Integer[] args) {

    R[args[2].intValue()] = LO;

    PC++;

  }

 

  //Mfhi

  public void mfhi(Integer[] args) {

    R[args[2].intValue()] = HI;

    PC++;

  }

 

  //Called last

  public void finish() {

    System.out.println("L1 hits: " + DMEMH.getNumHits());

    System.out.println("L1 misses: " + DMEMH.getNumMisses());

  }

 

  public void afterInst() {

    if (branch) {

      branch = false;

      delaySlot = true;

    }

    if (delaySlot) {

      delaySlot = false;

      PC = target;

    }

  }

}

 

Mem:

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2003</p>

 * <p>Company: </p>

 * @author not attributable

 * @version 1.0

 */

 

public class Mem {

  //Replacement policies

  public static  final int FIFO = 0;

  public static final int LRU = 1;

  public static final int RANDOM = 2;

 

  public long vals[];

  //Latency

  int latency;

  static int totalLatency;

 

  public Mem() {

    totalLatency = 0;

    vals = new long[200000];

  }

  public long getWord(int addr){

    return 0;

  }

  public void putWord(int addr, long data){

  }

  public long getNumHits(){

   return 0;

 }

 public long getNumMisses(){

   return 0;

 }

 

}

 

Parser:

package adlsim;

 

/**

 * <p>Title: </p>inde

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2002</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

import java.io.*;

public class Parser {

  public String hexFile= "";

  public int index = 0;

  public int indexLogic=0;

  public Element[] element = new Element[1000];

  public LogicElement[] elementLogic = new LogicElement[1000];

  public LogicElement[] el;

  public int[] dataAddr= new int[600];

  public int[] nodeNum = new int[600];

  public int[] nodeNumLogic = new int[600];

  public String[] ID = new String[600];

  public String[] IDAnalog = new String[600];

  public String[] IDLogic = new String[600];

  public String[] mcuName = new String[600];

  int IDIndex = 0;

  int IDIndexAnalog = 0;

  int IDIndexLogic = 0;

  Element[] e;

  FileReader f; // declare a file reader object

  Compiler C = new Compiler();

 

  public Element[] Parse(String S){

   try{

 

    // Create a new file reader

    // connected to S

    f = new FileReader(S);

    BufferedReader br = new BufferedReader(f);

    char[] temp0 = (br.readLine()).toCharArray();

 

    while(!(getWord(temp0,1)).equals("end")){

 

 

      String type = getWord(temp0,1);

      //System.out.println("TYPE is= "+type);

      if(type.equals("R")){

 

          element[index] = new Element(C.G,Integer.decode(getWord(temp0,2)).intValue(),

                           Integer.decode(getWord(temp0,3)).intValue(),-1,-1,

                           Math.pow(Integer.decode(getWord(temp0,4)).intValue(),-1),-1,-1,-1);

      }

      else if (type.equals("PORT")){

 

          element[index] = new Element(C.VSRC,0,Integer.decode(getWord(temp0,2)).intValue(),

                          -1,-1,0,1,Integer.decode(getWord(temp0,4)).intValue(),

                          Integer.decode(getWord(temp0,3)).intValue());

          element[index].MCU = getWord(temp0,5);

      }

      else if(type.equals("OPAMP")){

        element[index] = new Element(C.OpAmp,Integer.decode(getWord(temp0,2)).intValue(),

                      Integer.decode(getWord(temp0,3)).intValue(),Integer.decode(getWord(temp0,4)).intValue(),

                      -1,-1,-1,-1,-1);

      }

      else if(type.equals("AND")){

        elementLogic[indexLogic]=new LogicElement(1,Integer.decode(getWord(temp0,2)).intValue(),

                                Integer.decode(getWord(temp0,3)).intValue(),

                                Integer.decode(getWord(temp0,4)).intValue());

      }

      else if(type.equals("OR")){

        elementLogic[indexLogic]=new LogicElement(2,Integer.decode(getWord(temp0,2)).intValue(),

                                Integer.decode(getWord(temp0,3)).intValue(),

                                Integer.decode(getWord(temp0,4)).intValue());

      }

      else if(type.equals("NOT")){

        elementLogic[indexLogic]=new LogicElement(3,Integer.decode(getWord(temp0,2)).intValue(),

                                Integer.decode(getWord(temp0,3)).intValue(),1);

      }

      else if(type.equals("DFF")){

        elementLogic[indexLogic]=new LogicElement(4,Integer.decode(getWord(temp0,2)).intValue(),

                                Integer.decode(getWord(temp0,3)).intValue(),

                                Integer.decode(getWord(temp0,4)).intValue());

      }

      else if(type.equals("DUMP")){

        int tempIndex = 3;

        mcuName[IDIndex] = getWord(temp0,2);

        while(!getWord(temp0,tempIndex).equals("ENDDUMP")){

          //System.out.println("the word is="+getWord(temp0,tempIndex));

          ID[IDIndex] = getWord(temp0,tempIndex);

          dataAddr[IDIndex]= Integer.decode(getWord(temp0,(tempIndex+1))).intValue();

          IDIndex++;

          tempIndex = tempIndex +2;

        }

 

     }

     else if(type.equals("DUMPLOGIC")){

        int tempIndex = 2;

        while(!getWord(temp0,tempIndex).equals("ENDDUMP")){

          //System.out.println("the word is="+getWord(temp0,tempIndex));

          IDLogic[IDIndexLogic] = getWord(temp0,tempIndex);

          nodeNumLogic[IDIndexLogic]= Integer.decode(getWord(temp0,(tempIndex+1))).intValue();

          IDIndexLogic++;

          tempIndex = tempIndex +2;

        }

     }

      else if(type.equals("DUMPANALOG")){

        int tempIndex = 2;

        while(!getWord(temp0,tempIndex).equals("ENDDUMP")){

          //System.out.println("the word is="+getWord(temp0,tempIndex));

          IDAnalog[IDIndexAnalog] = getWord(temp0,tempIndex);

          nodeNum[IDIndexAnalog]= Integer.decode(getWord(temp0,(tempIndex+1))).intValue();

          IDIndexAnalog++;

          tempIndex = tempIndex +2;

        }

      }

      else if (type.equals("MCU")){

          //System.out.println(getWord(temp0,2));

          hexFile = getWord(temp0,2);

 

      }

      if((!type.equals("MCU"))&(!type.equals("DUMP"))&(!type.equals("DUMPANALOG"))

      &(!type.equals("AND"))&(!type.equals("OR"))&(!type.equals("DFF"))

      &(!type.equals("NOT"))&(!type.equals("DUMPLOGIC"))){

        index++;

      }

      if(type.equals("AND")|type.equals("OR")|type.equals("DFF")

      |type.equals("NOT")){

      //System.out.println("HEREEEEEE9999999999");

        indexLogic++;

      }

      temp0 = (br.readLine()).toCharArray();

    }

    index--;

    indexLogic--;

    //System.out.println("INDEX="+index);

     e = new Element[index+1];

    for(int i = 0; i<e.length; i++){

      e[i] = element[i];

    }

    el = new LogicElement[indexLogic+1];

    for(int i = 0; i<el.length; i++){

      el[i] = elementLogic[i];

    }

   }

   catch (Exception e){

 

    System.err.println ("Error reading file5555");

 

 

  }

  //System.out.println(e.length);

  return e;

  }

  public String getWord(char[] ch, int wordNum){

 

    boolean endFound = false;

    boolean startFound = false;

    int wordCount = 0;

    int wordStart =0;

    int wordEnd = 0;

    for(int i = 1; i <ch.length; i++){

        //System.out.println("CH length="+ch.length);

        if(((ch[i-1]!=' ')&&(ch[i]==' '))|(i ==ch.length-1))

          wordCount++;

        if((wordCount == wordNum-1)&&(ch[i-1]==' ')&&(ch[i]!=' ')&&!startFound){

          wordStart = i;

          startFound=true;

        }

        if((wordCount==wordNum)&&(!endFound)){

          if(i==ch.length-1)

            wordEnd=i+1;

          else

            wordEnd=i;

          endFound=true;

        }

      }

    //System.out.println("END="+wordEnd+"Start= "+wordStart);

    //System.out.println(String.copyValueOf(ch,wordStart,wordEnd-wordStart+1));

    return (String.copyValueOf(ch,wordStart,wordEnd-wordStart));

  }

}

 

Solver:

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2002</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

 

public class Solver {

  String vars[];// = new String[1];

  String varsLogic[];

  String varsAnalog[];

  VCD vcd = new VCD();

  XLS xls = new XLS();

  boolean[][] valLogic;

  long[][] val;

  double[][] valAnalog;

  byte PORTCInit = 0;

  byte PORTCFinal = 0;

 

  int dummy = 0;//DEBUG*********************************

  double temp  = 0;//DEBUG*****************************************

  long[] cTime = new long[100];//********************Debug

    int cTimeIndex = 0;

  double tempPort = 0;

   public double[] Solve(double[][]A0,double[]z0){

 

   int maxrow;

   int n= A0.length;

   double tmp;

   double[]x = new double[A0.length];

   double[][]a = new double[A0.length][A0.length+1];

 

    for(int i = 0; i<A0.length; i++){

      for(int j = 0; j<A0.length; j++)

        a[i][j]=A0[i][j];

    }

    for(int i =0; i<A0.length; i++)

      a[i][A0.length]=z0[i];

 

   for (int i=0;i<n;i++) {

 

      /* Find the row with the largest first value */

      maxrow = i;

      for (int j=i+1;j<n;j++) {

         if (Math.abs(a[j][i]) > Math.abs(a[maxrow][i]))

            maxrow = j;

      }

 

      /* Swap the maxrow and ith row */

      for (int k=i;k<n+1;k++) {

         tmp = a[i][k];

         a[i][k] = a[maxrow][k];

         a[maxrow][k] = tmp;

      }

 

 

      /* Eliminate the ith element of the jth row */

      for (int j=i+1;j<n;j++) {

         for (int k=n;k>=i;k--) {

            a[j][k] -= a[i][k] * a[j][i] / a[i][i];

         }

      }

   }

 

   /* Do the back substitution */

   for (int j=n-1;j>=0;j--) {

      tmp = 0;

      for (int k=j+1;k<n;k++)

         tmp += a[j][k] * x[k];

      x[j] = (a[j][n] - tmp) / a[j][j];

   }

 

   return x;

 

   }

 

 

 

  //Solve a system of non-linear equations for DC analyses using Newton-Raphson algorithm

  //where Ax=z, epsilon is a small value to test for convergence, and e is an

  //array containing the elements in the circuit

  public double[] SolveNL(double[][]A,double[]z, double epsilon, Element[] e){

   /* for(int i = 0; i<A.length; i++){

    z[i]=0;

      for(int j = 0; j<A.length; j++)

        A[i][j]=0;

        }*/

    //Done = true when the solution converges

    boolean Done = false;

    //noOfNodes in the circuit

    int noOfNodes = 0;

    //Initialize linear circuit compiler

    Compiler C = new Compiler();

    //Current results of the NR algorithm

    double[] x = new double[A.length];

    //Results from the previous iteration of the NR algorithm

    double[] xPrev =new double[x.length];

 

    //Find the # of nodes in the circuit & generate linear models of the non-linear elements

    //for the next iteration of the NR algorithm

    for(int i = 0; i< e.length; i++){

      //Determine the number of nodes

      if( Math.max( Math.max(e[i].nj,e[i].nk),Math.max(e[i].np,e[i].nq)) > noOfNodes){

        noOfNodes = Math.max(Math.max(e[i].nj,e[i].nk),Math.max(e[i].np,e[i].nq));

        }

    }

    for(int i = 0; i< e.length; i++){

      //Element processed is a diode

      if(e[i].TYPE == C.D){

        //Guess the initial diode voltage as 0.7

        double vd = 0.7;

        //Calculate Gd for this iteration

        double Gd = e[i].pnl1*e[i].pnl2*Math.exp(e[i].pnl2*vd);

        //Calculate Ids for this iteration

        double Ids = e[i].pnl1*(Math.exp(e[i].pnl2*vd)-1)-Gd*vd;

        //Generate linear model of the diode for the next iteration

        //and update the array of elements

        e[i] = new Element(C.D,e[i].nj,e[i].nk,e[i].np,e[i].nq,Gd,Ids,e[i].pnl1,e[i].pnl2);

      }

    }

 

    //Keep on iterating until the results converge to within +/- epsilon

    //of the actual values

    while(!Done){

      //Compile the circuit using the new element array

      A = C.Compile(e,noOfNodes);

      //Update previous results

      for(int i = 0; i<x.length; i++){

        xPrev[i] = x[i];

      }

 

      //Get the new results

      x = Solve(A,C.z);

      //Check for convergence

      Done = true;

      for(int i =0; i <x.length ; i++){

        if(Math.abs(x[i]-xPrev[i])>epsilon)

          Done = false;

      }

      //Process the element list & recompile

      for(int i = 0; i< e.length; i++){

        //Element processed is a diode

        if(e[i].TYPE == C.D){

          //Value of the positive terminal voltage

          double tempIn = 0;

          //Value of the negative terminal voltage

          double tempOut = 0;

          //voltage accross the diode

          double vd = 0;

          //Get the voltages on the +/- terminals

          if(e[i].nk >0)

            tempIn = x[e[i].nk-1];

          if(e[i].nj >0)

            tempOut = x[e[i].nj-1];

          //Calculate diode voltage

          vd = tempIn - tempOut;

          //Calculate Gd for this iteration

          double Gd = e[i].pnl1*e[i].pnl2*Math.exp(e[i].pnl2*vd);

          //Calculate Ids for this iteration

          double Ids = e[i].pnl1*(Math.exp(e[i].pnl2*vd)-1)-Gd*vd;

          //Generate linear model of the diode for the next iteration

          //and update the array of elements

          e[i] = new Element(C.D,e[i].nj,e[i].nk,e[i].np,e[i].nq,Gd,Ids,e[i].pnl1,e[i].pnl2);

        }

    }

  }

    return(x);

  }

 

   //Perfrom AC analyses with time-step h

   public double[] SolveAC(double[][]A,double[]z, double epsilon, double h, double t, Element[] e,

                          ADLSimulator MCUs[], String[] ID, int[] addr, int IDIndex,String[] mcuName,

                          String[] IDAnalog, int[] nodeNum, int IDIndexAnalog,

                          String[] IDLogic, int[] nodeNumLogic, int IDIndexLogic, Logic logic){

    if(IDIndexAnalog!=0)

      valAnalog = new double[10001][IDIndexAnalog+1];

    else

      valAnalog = new double[1][2];

    if(IDIndex!=0)

      val = new long[IDIndex][10001];

    else

      val = new long[1][2];

    if(IDIndexLogic!=0)

      valLogic = new boolean[IDIndexLogic][10001];

    else

      valLogic = new boolean[1][2];

    Element[] element = new Element[e.length];

    Compiler C = new Compiler();

    double x[] = new double[A.length];

    double currentTime = 0;

    int noOfNodes = 0;

    for(int i = 0; i< element.length; i++){

      element[i] = new Element(e[i].TYPE, e[i].nj, e[i].nk, e[i].np, e[i].nq,

                               e[i].p, e[i].pnl0, e[i].pnl1, e[i].pnl2);

      element[i].MCU = e[i].MCU;

    }

    for(int i = 0; i< e.length; i++){

      //Determine the number of nodes

      if( Math.max( Math.max(e[i].nj,e[i].nk),Math.max(e[i].np,e[i].nq)) > noOfNodes){

        noOfNodes = Math.max(Math.max(e[i].nj,e[i].nk),Math.max(e[i].np,e[i].nq));

        }

    }

    for(int i = 0; i < MCUs.length; i++)

      MCUs[0].init();

    while(currentTime < t){

 

      for(int i = 0; i<element.length; i++){

        //Capacitor

        if(element[i].TYPE == C.CAC){

          //Temporary variables for calculating capacitor voltage

          double tempPlus =0;

          double tempMinus = 0;

          //Get the voltages on the two nodes connected to

          //the capacitor

          if(element[i].nj > 0)

            tempPlus=x[element[i].nj -1];

          if(element[i].nk > 0){

            tempMinus = x[element[i].nk - 1];

          }

          //Subtract the voltages to get Vcap.

          double v = tempPlus - tempMinus;

          //Generate a new linear capacitor model for the next iteration

          //based on the capacitor voltage.

          element[i] = new Element(element[i].TYPE, element[i].nj,element[i].nk,element[i].np,element[i].nq,

                                    element[i].p,-1*element[i].p*v,element[i].pnl1,element[i].pnl2);

 

 

        }

        //VAC

        if(element[i].TYPE == C.VAC){

 

 

        temp = Math.cos(currentTime);

 

          element[i] = new Element(element[i].TYPE, element[i].nj,element[i].nk,element[i].np,element[i].nq,

                       temp,element[i].pnl0,element[i].pnl1,element[i].pnl2);

        }

      //PORT

      if((element[i].TYPE == C.VSRC)&(element[i].pnl0==1)){

        ADLSimulator MCU = null;

        for(int j = 0; j < MCUs.length; j++){

          //String[] s0 = MCUs[j].toString().split("@");

          String s1 = MCUs[j].name;//s0[0].substring(7);

         // System.out.println(element[i].MCU+"-----------------------------------------element"+j);

         // System.out.println(s1+"-----------------------------------------s1");

          if(element[i].MCU.equals(s1)){

            MCU = MCUs[j];

            break;

          }

        }

        //System.out.println("PORT DONE");

        if(MCU.getBit(MCU.DMEM[(byte)element[i].pnl2],(int)element[i].pnl1)){

          tempPort = 5;

        }

        else{

          tempPort = 0;

        }

        String mcu = element[i].MCU;

        element[i] = new Element(element[i].TYPE,element[i].nj,element[i].nk,element[i].np,element[i].nq,

                    tempPort,element[i].pnl0,element[i].pnl1,element[i].pnl2);

        element[i].MCU = mcu;

 

      }

      }

      /*******INITIAL Values of PORTC*******/

     // PORTCInit = MCU.regFileIO[21];

      /***********************************/

      for(int i = 0 ; i < MCUs.length; i++){

        if (currentTime >= MCUs[i].cycleNum) {

          MCUs[i].run();

        }

      }

      /*******FINAL Value of PORTC*******/

    //  PORTCFinal = MCU.regFileIO[21];

      /***********************************/

      double tempX = x[17];

 

 

      A = C.Compile(element,noOfNodes);

      x = SolveNL(A,C.z,epsilon,element);

 

 

       // x = Solve(A,C.z);

      currentTime = currentTime + h;

      dummy++;

 

      //System.out.println("TEST");

      ///*****HANDLE DUMPS***********************////////////

       String propogate = null;

      for(int i = 0 ; i < mcuName.length; i++){

 

        if(mcuName[i] != null){

          propogate = mcuName[i];

        }

        else{

          mcuName[i] = propogate;

        }

      }

      if(IDIndex!=0){

        for(int i=0; i<IDIndex; i++){

          ADLSimulator MCU = null;

          //System.out.println(mcuName[i]);

          for(int j = 0; j < MCUs.length; j++){

            if(MCUs[j].name.equals(mcuName[i]))

              MCU = MCUs[j];

          }

          //System.out.println(MCU);

            val[i][(int)currentTime]=MCU.DMEM[addr[i]];

 

        }

      }

      /********LOGIC******/

      if(IDIndexLogic!=0){

        for(int i = 0; i<logic.externalInputs.length; i++){

         // System.out.println("EXT[i]="+logic.externalInputs[i]);

        }

        //System.out.println("****************************************************");

        boolean[] newLogicVals= new boolean[logic.oldNodeVals.length];

        for(int i = 0; i<newLogicVals.length;i++){

          newLogicVals[i] = logic.oldNodeVals[i];

        }

        for(int i = 0; i<logic.externalInputs.length; i++){

          if(logic.externalInputs[i]&(i==0)){

            newLogicVals[i] = false;

          }

          if(logic.externalInputs[i]&(i<x.length)&(i>0)){

            newLogicVals[i] = (x[i-1]>3.5);

          }

        }

        boolean currentVals[] = logic.SolveLogic(newLogicVals);

        for(int i= 0; i<IDIndexLogic;i++){

          valLogic[i][(int)currentTime-1] = currentVals[nodeNumLogic[i]];

        }

      }

 

      /*******************/

     // if(analogMode==0){

        if(IDIndexAnalog!=0){

          valAnalog[(int)currentTime][0]=currentTime;

          for(int i=1; i<IDIndexAnalog+1; i++){

            valAnalog[(int)currentTime][i]=x[nodeNum[i-1]-1];

          }

        }

 

    }

    for(int i = 0; i <MCUs.length; i++)

      MCUs[i].finish();

    if(IDIndex!=0){

    vars = new String[IDIndex];

    //System.out.println("IDINDEX="+IDIndex);

    for(int i = 0;i<IDIndex;i++){

      vars[i] = ID[i];

    }

    if(IDIndexLogic!=0){

    varsLogic = new String[IDIndexLogic];

    //System.out.println("IDINDEX="+IDIndex);

    for(int i = 0;i<IDIndexLogic;i++){

      varsLogic[i] = IDLogic[i];

    }

    vcd.makeVCD(vars,varsLogic,val,valLogic,"VCDRESULTS.vcd");

    }

    else

    vcd.makeVCD(vars,val,"VCDRESULTS.vcd");

    }

    /*****makevcd*****/

    /******makexls****/

    varsAnalog = new String[IDIndexAnalog+1];

    varsAnalog[0] = "Time";

    for(int i = 1;i<IDIndexAnalog+1;i++){

      varsAnalog[i] = IDAnalog[i-1];

    }

    xls.makeXLS(varsAnalog,valAnalog,"XLSRESULTS.xls");

    /******makexls****/

    return x;

  }

}

 

VCD:

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2002</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

import java.io.*;

 

public class VCD {

  ADLSimulator MCU= new ADLSimulator();

  FileOutputStream f;

  //Return a string representing the binary equivalent of n

  public String decimalToBinary(int n){

    String S = "";

    for(int i = 31; i>=0; i--){

      if(MCU.getBit(n,i))

        S = S + "1";

      else

        S = S + "0";

    }

    return S;

  }

  //Return a string representing the binary equivalent of n

  public String decimalToBinary(long n){

    String S = "";

    for(int i = 63; i>=0; i--){

      if(MCU.getBit(n,i))

        S = S + "1";

      else

        S = S + "0";

    }

    return S;

  }

 

  /*******OVERLOADED METHOD**************/

  //Create a VCD file given an array of values and a file name

  public void makeVCD(String[] vars,String[]varsLogic,long[][] val,boolean[][] valLogic, String S){

    try{

    f = new FileOutputStream(S);

    PrintStream pr = new PrintStream(f);

 

    pr.println("$timescale");

    pr.println("1 ns");

    pr.println("$end");

 

    for(int i=0;i<vars.length;i++){

     pr.println("$var reg 8 "+vars[i]+" "+vars[i]+" "+"$end");

    }

    for(int i=0;i<varsLogic.length;i++){

     pr.println("$var reg 1 "+varsLogic[i]+" "+varsLogic[i]+" "+"$end");

    }

    pr.println("$dumpvars");

 

 

    for(int cycleIndex=0; cycleIndex< val[0].length;cycleIndex++){

      if(cycleIndex!=0){

        pr.println("#"+cycleIndex);

      }

      for(int valIndex= 0; valIndex < val.length; valIndex++){

        pr.println("b"+decimalToBinary(val[valIndex][cycleIndex])+" "+vars[valIndex]);

      }

      for(int valLogicIndex= 0; valLogicIndex < valLogic.length; valLogicIndex++){

        if(valLogic[valLogicIndex][cycleIndex])

          pr.println("b1 "+varsLogic[valLogicIndex]);

        else

          pr.println("b0 "+varsLogic[valLogicIndex]);

      }

    }

    pr.println("$end");

    }

    catch (Exception e){

      System.err.println ("Error writing file");

    }

 

  }

  //Create a VCD file given an array of values and a file name

  public void makeVCD(String[] vars,long[][] val, String S){

    try{

    f = new FileOutputStream(S);

    PrintStream pr = new PrintStream(f);

 

    pr.println("$timescale");

    pr.println("1 ns");

    pr.println("$end");

 

    for(int i=0;i<vars.length;i++){

     pr.println("$var reg 8 "+vars[i]+" "+vars[i]+" "+"$end");

 

 

    }

 

    pr.println("$dumpvars");

 

 

    for(int cycleIndex=0; cycleIndex< val[0].length;cycleIndex++){

      if(cycleIndex!=0){

        pr.println("#"+cycleIndex);

      }

      for(int valIndex= 0; valIndex < val.length; valIndex++){

        pr.println("b"+decimalToBinary(val[valIndex][cycleIndex])+" "+vars[valIndex]);

      }

    }

    pr.println("$end");

    }

    catch (Exception e){

      System.err.println ("Error writing file");

    }

 

  }

}

 

XLS:

package adlsim;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

 * <p>Copyright: Copyright (c) 2002</p>

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

import java.io.*;

public class XLS {

  ADLSimulator MCU= new ADLSimulator();

  FileOutputStream f;

  //Create an XLS file given an array of values and a file name

  public void makeXLS(String[] vars,double[][] val, String S){

     try{

      f = new FileOutputStream(S);

      PrintStream pr = new PrintStream(f);

      for(int i=0; i < vars.length; i++){

        pr.print(vars[i]+'\t');

      }

      pr.println();

      for(int cycleIndex = 0; cycleIndex < val.length; cycleIndex++){

          for(int varIndex = 0; varIndex <val[0].length; varIndex++){

            pr.print(val[cycleIndex][varIndex]);

            pr.print('\t');

          }

          pr.println();

      }

      }

    catch (Exception e){

      System.err.println ("Error writing file5555555555555555555");

    }

 

  }

}