Mixed Signal AVR Simulator       

   ECE491 Project by Engin Ipek Advisor: Bruce Land

Introduction                          High Level Design                           Results                       Netlist Files                           Listing                        Improvements

 Introduction:

Today, one of the most efficient and cost-effective methods of placing random logic in electronic equipment is using a microcontroller. Due to their high I/O capabilities, low cost, low power and off-the-shelf availability, microcontrollers find a wide range of applications in the embedded design space, from engine control systems to cellular phones, calculators and digital clocks. In many of these real-time applications, the microcontroller is used to interface to the external world in order to monitor, generate or sample analog and digital signals by interacting with other hardware. In such cases where the design contains both analog and digital signals, it is usually insufficient to simulate the analog parts using a transient analysis algorithm and the digital parts using a logic simulator. Although this approach may be adequate for a restricted number of simple circuits, in many complex systems the digital part may produce analog signals that are combined with analog signals in analog circuitry. Moreover, the digital ports might have loading effects on the analog circuitry and the analog components may affect the current sinking/sourcing capabilities of the digital components.  Having the ability to simulate such effects is an indispensable tool when making mixed-signal design decisions (eg, the effect of switching noise from a microcontroller on a sensitive scanning-tunneling microscope IrPt tip) and necessitates the implementation of such simulators for microcontrollers.

In an attempt to provide a solution to this problem, I designed a mixed signal simulator that can be used to analyze the analog, digital (gate level) and RTL level behavior of small systems built around Atmel AT90S8515 series microcontrollers for my ECE 491 project. The simulator allows the user to set up mixed-signal systems and to specify the programs to run on the microcontrollers by using a simple hardware-description language whose syntax is similar to Spice net-list format. In order to run the simulator, the user provides a net-list file listing all of the electrical connections in the system, an optional stimulus file describing external events (button pushes, received signals, noise etc.) and a hex file describing the initial state of the instruction and data memories of the microcontroller (these hex files can be easily generated from assembly files using ATMEL AVR Studio). Once these files have been provided, the simulator compiles the circuit, checks for potential problems and reports any errors. Once a circuit has been compiled successfully, the user is able to run the hex files and view the contents of the memory and the register file. It is also possible to perform DC and transient analyses on the analog circuitry, timing analysis on the logic components (CMOS, TTL etc.), and behavioral analyses on any additional systems included in the design. An RS232 terminal emulator is also implemented to model communication using the UART of the 8515. The user has the ability to edit models for new devices or to change certain parameters on the existing devices.  A summary of the devices that are provided by the simulator as library models is given below

*   Linear resistors and capacitors.

*   Ideal sources, controlled sources

*   Ideal Op-Amps

*   Diodes

*   MOSFETs (Spice Level 1 Model) and BJTs

*   Noise sources

*   Buttons

*   Logic gates and flip-flops

*   AT90S8515 series microcontrollers

*   RS232 terminal emulator

The results of the analog simulation are output in an excel file while the digital and RTL level simulation results can be viewed using GTKwave.

High Level Design:

 

The simulator was written 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 simulation begins when the parser reads the netlist file and determines the location of the hex file containing an image of the memory at time t=0. This information is passed onto the hex-reader, which reads the hex file and loads the appropriate data and instructions into the RTL level model of the 8515. This loaded model is then given to the solver class as an input. As the parser goes through the netlist file, it also creates an array of the logic elements (logic gates and flip-flops) that are referenced by the designer. Every logic element object in this array includes the type of the element (eg, D flip-flop) and the connections to its fan-in and fan-out. This array is passed to the logic class which instantiates a logic solver based on the nodes, connections and initial inputs in the Logic Element [] array. This logic solver is then given to the Solver class as an input. Finally, the parser creates an array of analog elements with initial conditions on nodes at time t=0, and passes this array to the compiler class. The compiler generates linear models of every component for the next iteration of the simulation and uses these linear models with the initial conditions to generate a matrix equation of the form Ax=z where A is an n*n matrix (for n analog components) and z is a vector of length n. Once the logic simulator, the RTL level model of the microcontroller and the matrix equation are passed to the solver, the solver determines the dependencies between the submitted nodes and solves the matrices and logic equations for the next time step. It also advances the simulation of the microcontroller by one clock cycle. The results from the current time step are returned to the compiler, which re-generates the linear models for the next iteration and passes A and z back to the solver. This cycle goes on until the user specified simulation termination time is reached. At that point, the solver passes the values that it has stored throughout the simulation to the xls and vcd classes, which generate an excel file containing the analog results and a vcd file (to be viewed by GTKwave) containing the RTL level and digital results, respectively.

 

The non-linear equations are solved using the Newton-Raphson algorithm while the transient analysis is based on the backward-euler integration formula. At every iteration, the results for the shared nodes of all three simulations (RTL, logic and analog) are converted to the appropriate signal domain and passed as an input to the appropriate model  (eg, the digital outputs of the microcontroller that are inputs to analog circuitry are converted into analog and passed onto the analog compiler class for the next iteration). Because of the use of the backward-euler formula, only stable circuits can be successfully simulated. Hence, oscillators should be implemented using the voltage sources and not other circuits that have stability issues. The wien-bridge oscillator, for instance, will have a high damping constant associated with it and hence the simulation results will not reflect the physical reality.

 

Results:

 

The results of the simulation were found accurate to 9 decimal places when p-Spice analog simulator was taken as a reference. The microcontroller was also found to be perfectly cycle accurate in all test cases. The following circuit & corresponding results are provided as typical outcomes of the simulation, and a step-by-step explanation of writing the netlist file for this example is listed. A more detailed explanation of the netlist format is provided under the “Netlist Files” section.

 

Consider the following circuit that generates a 4.95kHz sinewave. PORTC of the microcontroller is set up to generate a new value every 1/16 of a cycle so that a total of 16 samples/cycle of the sinewave can be obtained. The output is then converted into analog using an R-2R ladder DAC and this signal is amplified by an inverting op-amp circuit of gain –2.  To illustrate the use of logic gates, the 2 least significant bits of portc are input to an and gate and the result is or’ed with bit 2 of portc.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


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

The first line gives the name of the hex file to be loaded into the memory. The DAC

is defined next, followed by the connections to portc and the logic gates.  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 netlist file format can be found under the netlist files section.


The C code that is running on the microcontroller is provided below. To run the simulator, this file was compiled by Code Vision AVR C Compiler with

“Intel Hex” selected as the output file format.

 

 

//Sine wave generator using C

//4.95kHz frequency

#include <90s8515.h>

//Define constants

#define prescale1 1

#define clear_on_match 8

//Sample number

unsigned char sample ; 

 

//Table of sine values

flash unsigned char sinetable[16]={0x80, 0xb1, 0xda, 0xf6, 0xff, 0xf6, 0xda, 0xb1,

                                                                                                   0x80, 0x4f, 0x26, 0x0a, 0x00, 0x0a, 0x26, 0x4f};

 

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

//timer 1 compare-match A ISR

interrupt [TIM1_COMPA] void cmpA_overflow(void)

  {      

  PORTC = sinetable[sample++] ; //PORTC = Next sine value

  if (sample == 16) sample=0 ;  //Go back to beginning of table if period complete

  } 

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

 

void main(void)

  {

            sample = 0 ;               //Initialize sample # to beginning of table

            TIMSK = 0x40 ;         //Timer 1 CompareA 

            DDRC = 0xff ;            //port C are outputs

            OCR1A = 100;           // Set up OCR1A       

            TCCR1B = prescale1 + clear_on_match ;  

            //setup clear on match

            TCNT1 = 0;   

            //turn on all interrupts

            #asm

                        sei

            #endasm

            while(1){}       //Do nothing, wait for ISR to be called

  }

 

 

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 microcontroller spends the initial 3600 cycles running the boot code and consequently portc does not change during this time. The plot on the right shows the gain of the Op

Amp. As expected, the gain is equal to –2 and the amplifier is perfectly linear since it is an ideal Op Amp (R-squared = 1, y= -2x on the plot).

 

 

 

 

 

 

 

 

 

 


The results of the digital simulation are shown below. The top two rows show the values of portc and the output of the or gate, respectively.

 

 


 

 


The performance of the simulator was evaluated based on the ratio of the simulation time to real-time. Although the non-linear transient analysis used in the simulator has O(n2) asymptotic complexity, linear circuits such as the one shown above can be simulated reasonably fast. Since the program spends a significant amount of its time (30% for the example above) generating the output files, reducing the number of output nodes that the simulator saves (using dump statements) significantly improves performance. Hence, for fast simulations, only essential signals should be stored. The performance of the simulator for the sinewave generator example is shown below. As indicated by the plot, the simulator is approximately 700 times slower with respect to real time. For testing typical microcontroller – based designs, this performance is adequate. For instance, it takes roughly 1.5 minutes to simulate 1 million instructions of the sinewave generator, where 10000 instructions are enough to see 4 full cycles of the sinewave.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


           

Netlist Files:

As shown in the sinewave generator example, every netlist file begins with a statement of the form “MCU filename.hex” where filename.hex is the hex file that contains a memory image of the initial processor state. This statement is followed by a description of the connections in the circuit. In order to make these connections, the user assigns a unique number from 1 to n to each node, where n is the number of nodes in the circuit (excluding GND). By default, node 0 always corresponds to ground, but aside from this convention the user is free too select any number to correspond to any node. Connections are specified by listing the element name, the input and output nodes and the parameters related to the operation of the element. For instance, “R 1 2 1000”

places a 1k ohm resistor between nodes 1 and 2. A full list of the parameters that must be specified for every element is provided below. Connections to the microcontroller are made by statements of the form “PORT node_number IO_address bit_number” where node_number specifies the number assigned by the user, IO_address gives the address of the port and bit_number shows which bit of the port to connect. To store the values of any nodes, registers or memory locations and view them after the simulation, DUMP, DUMPANALOG and DUMPLOGIC statements are used. DUMP statement is used for the microcontroller, DUMPANALOG is used for analog signals and DUMPLOGIC is used for logic signals. These statements have the following general forms:

 

DUMP name1 memAddr1 name2 memAddr2 … end where “name1….N” is any string chosen by the user and memAddr is the memory address of the specific register/memory location that the user wants to view. The VCD file uses name1… nameN when displaying the results.  Since there is no memory address for the PC, the memAddr field should be “PC” when storing the PC (eg, DUMP mcuPC PC end).

 

DUMPANALOG name1 node1 name2 node2 … end where “name1…N” is any string chosen by the user and “node1…N” corresponds to the node number specified by the user.

 

DUMPLOGIC’s format is identical to DUMPANALOG.

 

Below is a list of the circuit elements supported:

 

R node1 node2 resistance (ohms)

C node1 node2 capacitance (F)

VDC neg_terminal pos_terminal voltage (V)

VAC neg_terminal pos terminal amplitude (V) freq (Hz) type (sine or cos or triangle or pulse)

VCCS neg_terminal pos_terminal neg_terminal_reference pos_terminal_reference coefficient

VCVS neg_terminal pos_terminal neg_terminal_reference pos_terminal_reference coefficient 

CCCS  neg_terminal pos_terminal neg_terminal_reference pos_terminal_reference coefficient

CCVS neg_terminal pos_terminal neg_terminal_reference pos_terminal_reference coefficient

DIODE neg_terminal pos_terminal area

NMOS source drain gate W L K’ Vt

PMOS source drain gate W L K’ Vt

NPN    collector emitter base alfaF alfaR Is Vt

PNP    collector emitter base alfaF alfaR Is Vt

OPAMP  pos_terminal neg_terminal output_terminal pos_supply_voltage(V) neg_supply_voltage(V)

PORT node_number IO_address bit_number

AND node1 node2 node_out

OR   node1 node2 node_out

DFF node_in, node_out, CLK

BUTTON node1 node2 stimulus_file_name button_name

VRANDOM neg_terminal pos_terminal stimulus_file_name vrandom_name

 

Buttons and random voltage sources have stimulus files associated with them. At each simulation step, the values for the buttons and random voltage

Sources are read from these files. An example stimulus file is provided below, assuming that button b1 and random voltage source v1 have been declared and tied to this stimulus file in the netlist:

 

#0

b1 0

v1 0

#5

b1 1

#10

b1 0

v1 2.45

end

 

In this example, the button is off and the random voltage source is outputting 0 volts at cycle 0 (cycle # of the mcu). At cycle 5, b1 turns on. At cycle 10, b1 turns off and v1 outputs 2.45 volts.

Improvements:

Given enough time, the simulator could easily be extended to handle multiple microcontrollers. Frequency domain analysis could also be implemented and more library models could be created.

Listing:

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

AT90S8515

Compiler

Element

HexReader

Logic

LogicElement

Parser

Solver

VCD

XLS

AT90S8515:

package avrsimmx;

 

/**

 * Title: AVRSimto

 * Description: Mixed Signal AVR Simulatorsyste

 * Copyright: Copyright (c) 2002R

 * Company: Cornell University

 * @author Engin Ipek

 * @version 1.0S

 */

 

public class AT90S8515 {

//Power down mode

boolean pwrDownMode = false;

 

//Idle mode

boolean idleMode = false;

 

//WatchDog timer Reset Signal

boolean wReset = false;

 

//# of CPU cycles passed so far

long cycleNum = 0;

 

//Skip current instruction

private boolean skip = false;

 

//Program counter

private int PC= 0;

 

//Stack Pointer

private int stackPtr = 0;

 

//Current Instruction fetched form instruction memory

private short instr = 0;

 

//IO Register File

byte[] regFileIO = new byte[64];

 

//General purpose working register file

byte[] regFile = new byte[32];

 

//Internal SRAM

byte[] SRAM = new byte[512];

 

//FLASH Program Memory

short[] FLASH = new short[0xfff];

 

//TCNT0 & TCNT1 Prescalers

int prescaler0 = 0;

int prescaler1 = 0;

 

int inc0 = 0;

int inc1 = 0;

//Top value for PWM

public int top = 0;

 

//Count Direction for PWM

//Counts up if true, down if false

public boolean countUp = true;

 

//Clear Counter1 (following a Compare Match)

public boolean clrTimer1 = false;

 

//Last cycle number where a timer was reset

long resetCycle0 = 0;

long resetCycle1 = 0;

 

//Value of TCNT0 before the instruction is executed

public byte TCNT0Init = 0;

 

//Value of cycleNum before the instruction is executed

public long cycleNumInit = 0;

 

//Value of TCCR0 before the instruction is executed

public byte TCCR0Init = 0;

 

//Value of prescaler0 & prescaler1 before the instruction is executed

public int prescaler0Init = 0;

public int prescaler1Init = 0;

//Value of TCNT1 before the instruction is executed

public int TCNT1Init = 0;

 

//Value of TCCR1A & TCCR1B before the instruction is executed

public byte TCCR1AInit = 0;

public byte TCCR1BInit = 0;

 

//Value of OCR1AH and OCR1AL before the instruction is executed

public byte OCR1AHInit = 0;

public byte OCR1ALInit = 0;

public int OCR1AInit = 0;

 

//OCR1A written for the first time

public boolean OCR1AWritten = false;

 

//Execute current instruction before jumping to ISR

public boolean waitForISR_TCNT0_OVF = true;

public boolean waitForISR_TCNT1_OVF = true;

public boolean waitForISR_TCNT1_COMPA = true;

public boolean waitForISR_TCNT1_COMPB = true;

//Execute current instruction before updating TCNT0

//when prescaler0 changes

public boolean waitForPrescaler0 = true;

 

//clrTimer1 Set to High

public boolean clrTimer1Set = false;

//Value of TCNT1

int TCNT1 = 0;

 

//Aliases for the registers

//byte SREG = regFileIO[0x3f];

//byte SPH = regFileIO[0x3e];

//byte SPL = regFileIO[0x3d];

//byte GIMSK = regFileIO[0x3b];

//byte GIFR = regFileIO[0x3a];

//byte TIMSK = regFileIO[0x39];

//byte TIFR = regFileIO[0x38];

//byte MCUCR = regFileIO[0x35];

//byte TCCR0 = regFileIO[0x33];

//byte TCNT0 = regFileIO[0x32];

//byte TCCR1A = regFileIO[0x2f];

//byte TCCR1B = regFileIO[0x2e];

//byte TCNT1H = regFileIO[0x2d];

//byte TCNT1L = regFileIO[0x2c];

//byte OCR1AH = regFileIO[0x2b];

//byte OCR1AL = regFileIO[0x2a];

//byte OCR1BH = regFileIO[0x29];

//byte OCR1BL = regFileIO[0x28];

//byte ICR1H = regFileIO[0x25];

//byte ICR1L = regFileIO[0x22];

//byte WDTCR = regFileIO[0x21];

//byte EEARH = regFileIO[0x1f];

//byte EEARL = regFileIO[0x1e];

//byte EEDR = regFileIO[0x1d];

//byte EECR = regFileIO[0x1c];

//byte PORTA = regFileIO[0x1b];

//byte DDRA = regFileIO[0x1a];

//byte PINA = regFileIO[0x19];

//byte PORTB = regFileIO[0x18];

//byte DDRB = regFileIO[0x17];

//byte PINB = regFileIO[0x16];

//byte PORTC = regFileIO[0x15];

//byte DDRC = regFileIO[0x14];

//byte PINC = regFileIO[0x13];

//byte PORTD = regFileIO[0x12];

//byte DDRD = regFileIO[0x11];

//byte PIND = regFileIO[0x10];

//byte SPDR = regFileIO[0x0f];cycl

//byte SPSR = regFileIO[0x0e];

//byte SPCR = regFileIO[0x0d];

//byte UDR = regFileIO[0x0c];

//byte USR = regFileIO[0x0b];

//byte UCR = regFileIO[0x0a];

//byte UBRR = regFileIO[0x09];

//byte ACSR = regFileIO[0x08];

 

//PORTS & PINS

public byte Pa;

public byte Pb;

public byte Pc;

public byte Pd;

 

//Pins

//PINA

public boolean PA0 = false;

public boolean PA1 = false;

public boolean PA2 = false;

public boolean PA3 = false;

public boolean PA4 = false;

public boolean PA5 = false;

public boolean PA6 = false;

public boolean PA7 = false;

 

//PINB

public boolean PB0 = false;

public boolean PB1 = false;

public boolean PB2 = false;

public boolean PB3 = false;

public boolean PB4 = false;

public boolean PB5 = false;

public boolean PB6 = false;

public boolean PB7 = false;

 

//PINC

public boolean PC0 = false;

public boolean PC1 = false;

public boolean PC2 = false;

public boolean PC3 = false;

public boolean PC4 = false;

public boolean PC5 = false;

public boolean PC6 = false;

public boolean PC7 = false;

 

//PIND

public boolean PD0 = false;

public boolean PD1 = false;

public boolean PD2 = false;

public boolean PD3 = false;

public boolean PD4 = false;

public boolean PD5 = false;

public boolean PD6 = false;

public boolean PD7 = false;

 

//Other pins

public boolean GND    = false;

public boolean VCC    = false;

public boolean XTAL1  = false;

public boolean XTAL2  = false;

public boolean ICP    = false;

public boolean ALE    = false;

public boolean _RESET = false;

public boolean OC1B   = false;

 

//Aliases for pins

 

//Simulator

public void run() {

 

// while(true){

  //*************PORTS & PINS***********//

  //Handle PORTA & PINA

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

    //regFileIO[0x1b]

    if(getBit(regFileIO[0x1a],i))

      Pa = setBit(Pa,i,getBit(regFileIO[0x1b],i));

    //PINA

    else

      regFileIO[0x19]=setBit(regFileIO[0x19],i,getBit(Pa,i));

  }

  //Handle PORTB & PINB

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

    //PORTB

    if(getBit(regFileIO[0x17],i))

      Pb = setBit(Pb,i,getBit(regFileIO[0x18],i));

    //PINA

    else

      regFileIO[0x16]=setBit(regFileIO[0x16],i,getBit(Pb,i));

  }

  //Handle PORTC & PINC

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

    //PORTC

    if(getBit(regFileIO[0x14],i))

      Pc = setBit(Pc,i,getBit(regFileIO[0x15],i));

    //PINA

    else

      regFileIO[0x13]=setBit(regFileIO[0x13],i,getBit(Pc,i));

  }

  //Handle PORTD & PIND

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

    //PORTD

    if(getBit(regFileIO[0x11],i))

      Pd=setBit(Pd,i,getBit(regFileIO[0x12],i));

    //PIND

    else

      regFileIO[0x10]=setBit(regFileIO[0x10],i,getBit(Pd,i));

  }

   //Store the value of cycleNum before executing the instruction*********************TRY W/o DEBUG

//  cycleNumInit = cycleNum;

  //*************INTERRUPTS**************//

  //Handle RESET

  if(_RESET == false){

  //  PC = 0;

  }

 

  //Handle Timer1_COMPA interrupt

  if(getBit(regFileIO[0x39],6) && getBit(regFileIO[0x38],6)){

    //I-bit is set

    if(getBit(regFileIO[0x3f],7)){

      //Store PC +1 in Stack

        SRAM[stackPtr-96] = (byte)(((PC  ) & 0x0000ff00) >>> 8);

 

        SRAM[stackPtr-96 - 1] = (byte)(((PC  ) & 0x0000ff));

        //Update stack pointer

        stackPtr = stackPtr - 2;

        regFileIO[0x3e] = (byte) ((stackPtr & 0x0000ff00) >>> 8);

        regFileIO[0x3d] = (byte) (stackPtr & 0x000000ff);

      PC = 4;

      //Clear OCF1A

      regFileIO[0x38]=setBit(regFileIO[0x38],6,false);

      //Clear the I-bit

      regFileIO[0x3f]=setBit(regFileIO[0x3f],7,false);

      //8 cycles to jumpt to ISR

      cycleNum = cycleNum+3;

      //Update TCNT1

      TCNT1 = TCNT1 + (3/prescaler1);

      regFileIO[0x2c] = (byte)(TCNT1);

      regFileIO[0x2d] = (byte)(TCNT1>>>8);

 

    }

  }

  //Handle Timer1_COMPB interrupt

  if(getBit(regFileIO[0x39],5) && getBit(regFileIO[0x38],5)){

    //I-bit is set

    if(getBit(regFileIO[0x3f],7)){

      PC = 5;

      //Clear OCF1A

      regFileIO[0x38]=setBit(regFileIO[0x38],5,false);

      //Clear the I-bit

      regFileIO[0x3f]=setBit(regFileIO[0x3f],7,false);

    }

  }

  //Handle Timer1_OVF Interrupt

  else if(getBit(regFileIO[0x39],7)&&getBit(regFileIO[0x38],7)){

       //I-bit is set

       if(getBit(regFileIO[0x3f],7)){

        //Store PC +1 in Stack

        SRAM[stackPtr-96] = (byte)(((PC  ) & 0x0000ff00) >>> 8);

 

        SRAM[stackPtr-96 - 1] = (byte)(((PC  ) & 0x0000ff));

        //Update stack pointer

        stackPtr = stackPtr - 2;

        regFileIO[0x3e] = (byte) ((stackPtr & 0x0000ff00) >>> 8);

        regFileIO[0x3d] = (byte) (stackPtr & 0x000000ff);

        //Clear TOV7

        regFileIO[0x38]=setBit(regFileIO[0x38],7,false);

        //Clear the I-bit

        regFileIO[0x3f]=setBit(regFileIO[0x3f],7,false);

        //8-Cycles necessary to vector to the ISR

        cycleNum= cycleNum+3;

        PC = 6;

        //Update TCNT1

        TCNT1 = TCNT1 + (3/prescaler1);

        regFileIO[0x2c] = (byte)(TCNT1);

        regFileIO[0x2d] = (byte)(TCNT1>>>8);

      }

  }

 

  //Handle Timer0_OVF Interrupt

  else if(getBit(regFileIO[0x39],1)&&getBit(regFileIO[0x38],1)){

 

        //I-bit is set

        if(getBit(regFileIO[0x3f], 7)){

 

          //Store PC +1 in Stack

          SRAM[stackPtr-96] = (byte)(((PC  ) & 0x0000ff00) >>> 8);

 

          SRAM[stackPtr-96 - 1] = (byte)(((PC  ) & 0x0000ff));

          //Update stack pointer

          stackPtr = stackPtr - 2;

          regFileIO[0x3e] = (byte) ((stackPtr & 0x0000ff00) >>> 8);

          regFileIO[0x3d] = (byte) (stackPtr & 0x000000ff);

          PC = 7;

          //Clear TOV0

          regFileIO[0x38]=setBit(regFileIO[0x38],1,false);

          //Clear the I-bit

          regFileIO[0x3f]=setBit(regFileIO[0x3f],7,false);

          //8-Cycles necessary to vector to the ISR

          cycleNum= cycleNum+3;

          //Update TCNT0

          regFileIO[0x32] = (byte)(regFileIO[0x32] + (3/prescaler0));

        }

      }

  //Store the value of cycleNum, TCNT0, TCCR0, TCNT1,TCCR1A, TCCR1B before executing the instruction

  cycleNumInit = cycleNum;

  TCNT0Init = regFileIO[0x32];

  TCCR0Init = regFileIO[0x33];

  TCCR1AInit = regFileIO[0x2f];

  TCCR1BInit = regFileIO[0x2e];

  TCNT1Init =((((int) regFileIO[0x2d]) << 8)&0x0000ff00) | (((int) regFileIO[0x2c]) & 0x000000ff);

  OCR1AHInit = regFileIO[0x2b];

  OCR1ALInit = regFileIO[0x2a];

  OCR1AInit = ((((int)OCR1AHInit)<<8)&(0x0000ff00)) | (((int)OCR1ALInit)&0x000000ff);

  //**************TIMER0**************//

  //Store previous prescaler0

  prescaler0Init = prescaler0;

  //Get prescaler0

  int cs0 = regFileIO[0x33] & 0x07;

  if(cs0 == 0)

    prescaler0 = 0;

  else if(cs0 == 1)

    prescaler0 = 1;

  else if(cs0 == 2)

    prescaler0 = 8;

  else if(cs0 == 3)

    prescaler0 = 64;

  else if(cs0 == 4)

    prescaler0 = 256;

  else if(cs0 == 5)

    prescaler0 = 1024;

 

  //**************TIMER1***************//

  //Store previous prescaler1

  prescaler1Init = prescaler1;

  //Get prescaler1

  int cs1 = regFileIO[0x2e] & 0x07;

  if(cs1 == 0)

    prescaler1 = 0;

  else if(cs1 == 1)

    prescaler1 = 1;

  else if(cs1 == 2)

    prescaler1 = 8;

  else if(cs1 == 3)

    prescaler1 = 64;

  else if(cs1 == 4)

    prescaler1 = 256;

  else if(cs1 == 5)

    prescaler1 = 1024;

 

 

  //PWM Mode Disabled

/* if((!getBit(regFileIO[0x2f],0))&&(!getBit(regFileIO[0x2f],1))){

 

 

    //Compare 1A Mode Select

    //Set the OC1A output line

    if(getBit(regFileIO[0x11],5)){

      if(getBit(regFileIO[0x2f],7) && getBit(regFileIO[0x2f],6))

        regFileIO[0x12]=setBit(regFileIO[0x12],5,true);

      else if(getBit(regFileIO[0x2f],7)&&!getBit(regFileIO[0x2f],6))

        regFileIO[0x12]=setBit(regFileIO[0x12],5,false);

      else if(!getBit(regFileIO[0x2f],7)&&getBit(regFileIO[0x2f],6))

        regFileIO[0x12]=setBit(regFileIO[0x12],5,!getBit(regFileIO[0x12],5));

    }

    //Compare 1B Mode Select

    //Set the OC1B output line

    if(getBit(regFileIO[0x2f],5) && getBit(regFileIO[0x2f],4))

        OC1B = true;

    else if(getBit(regFileIO[0x2f],5)&&!getBit(regFileIO[0x2f],4))

        OC1B = false;

    else if(!getBit(regFileIO[0x2f],5)&&getBit(regFileIO[0x2f],4))

        OC1B = !OC1B;

 

    //Clear Timer 1 if a compare match

    //occurred last cycle and the CTC1

    //bit was set

    if(clrTimer1){

      clrTimer1 = false;

      regFileIO[0x2d] = 0;

      regFileIO[0x2c] = 0;

    }

  }

*/

  //PWM Mode Enabled

 /* else{

    if((!getBit(regFileIO[0x2f],0))&&(getBit(regFileIO[0x2f],1)))

      top = 255;

    if((getBit(regFileIO[0x2f],0))&&(!getBit(regFileIO[0x2f],1)))

      top = 511;

    if((getBit(regFileIO[0x2f],0))&&(getBit(regFileIO[0x2f],1)))

      top = 1023;

 

    //Compare 1A Mode Select

    //Set the OC1A output line

    if(getBit(regFileIO[0x2f],7) && getBit(regFileIO[0x2f],6)){

      if(countUp)

        regFileIO[0x12]=setBit(regFileIO[0x12],5,true);

      else

        regFileIO[0x12]=setBit(regFileIO[0x12],5,false);

    }

    else if(getBit(regFileIO[0x2f],7)&&!getBit(regFileIO[0x2f],6)){

      if(countUp)

        regFileIO[0x12]=setBit(regFileIO[0x12],5,false);

      else

        regFileIO[0x12]=setBit(regFileIO[0x12],5,true);

    }

 

    //Compare 1B Mode Select

    //Set the OC1B output line

    if(getBit(regFileIO[0x2f],5) && getBit(regFileIO[0x2f],4)){

      if(countUp)

        OC1B = true;

      else

        OC1B = false;

    }

    else if(getBit(regFileIO[0x2f],5)&&!getBit(regFileIO[0x2f],4)){

      if(countUp)

        OC1B = false;

      else

        OC1B = true;

    }

 

    //Change Count Direction

    if((((((int) regFileIO[0x2d]) << 8)&0x0000ff00) | (((int) regFileIO[0x2c]) & 0x000000ff))==top)

      countUp = !countUp;

 

    //Count Up

    if(countUp){

      if(prescaler1 != 0){

        int temp = ((((int) regFileIO[0x2d]) << 8)&0x0000ff00) | (((int) regFileIO[0x2c]) & 0x000000ff);

        temp = (int)(temp + ((cycleNum - resetCycle1) % prescaler1));

        regFileIO[0x2d] = (byte) (temp >>> 4);

        regFileIO[0x2c] = (byte) temp;

      }

    }

    //Count Down

    else{

      if(prescaler1 != 0){

        int temp = ((((int) regFileIO[0x2d]) << 8)&0x0000ff00) | (((int) regFileIO[0x2c]) & 0x000000ff);

        temp = (int)(temp - ((cycleNum - resetCycle1) % prescaler1));

        regFileIO[0x2d] = (byte) (temp >>> 4);

        regFileIO[0x2c] = (byte) temp;

      }

    }

  }

*/

/*

  //Handle Overflows

  if((regFileIO[0x2d] == 0xff) && (regFileIO[0x2c] ==0xff))

    regFileIO[0x38]=setBit(regFileIO[0x38],7,true);

 

  if((regFileIO[0x2d] == regFileIO[0x2b]) && (regFileIO[0x2c] == regFileIO[0x2a])){

    regFileIO[0x38]=setBit(regFileIO[0x38],6,true);

    //Check the CTC1 bit

    if(getBit(regFileIO[0x2e],3))

       clrTimer1 = true;

  }

 

  if((regFileIO[0x2d] == regFileIO[0x29]) && (regFileIO[0x2c] == regFileIO[0x28])){

    regFileIO[0x38]=setBit(regFileIO[0x38],5,true);

  }

*/

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

 

  //Fetch the next instruction

  instr = FLASH[PC];

 

  //Destination (and source) register in the register file

  int Rd = (int) ((instr & 0x01f0) >>> 4);

  //Source register in the register file

  int Rr = (int) ((instr &0x000f)+((instr&0x0200)>>>5));

  //Constant data

  int K = (int) ((instr & 0x0f00) >>> 4) + (instr & 0x000f);

  //Constant address (signed)

  int k = (((int) ((instr >>> 3) & 0x003f)) << 25) >> 25;

  //Bit in the register file or I/O register

  int b = (int)(instr & 0x0007);

  //Bit in the status register

  int s = (int)((instr >>> 4) & 0x0007);

  //I/O location address

  int A = (int) ((instr >>> 4) & 0x000f);

  //Displacement for direct addressing

  int q = (int) ((instr & 0x00000007) | ((instr & 0x00000c00)>>>7) | ((instr & 0x00002000) >>> 8));

  //Result of the current instruction

  byte R = 0;

  //X,Y,Z registers

  int X = 0;

  int Y = 0;

  int Z = 0;

  X = ( ((X|regFile[27])<< 8) & (0x0000ff00))|(((int)regFile[26]) & 0x0000000ff);

  Y = ( ((Y|regFile[29])<< 8) & (0x0000ff00))|(((int)regFile[28]) & 0x0000000ff);

  Z = ( ((Z|regFile[31])<< 8) & (0x0000ff00))|(((int)regFile[30]) & 0x0000000ff);

 

  //Get current SP

  stackPtr = ((((int)regFileIO[(short)0x003e])&0x000000ff)<<8) | (((int)(regFileIO[0x3d]) & 0x0000000ff));

  //Decode and execute the instruction

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

  ////System.out.println("TCNT0="+ regFileIO[0x32]);

  ////System.out.println("TCNT1Lo="+regFileIO[0x2c]);

  ////System.out.println("TCNT1Hi="+regFileIO[0x2d]);

  ////System.out.println("TIMSK="+ regFileIO[0x39]);

  ////System.out.println("prescaler1="+prescaler1);

  ////System.out.println("TIFR="+ regFileIO[0x38]);

  ////System.out.println("PORTC = "+regFileIO[0x15]);

  ////System.out.println("INSTR:" + instr);

  ////System.out.println("PC="+PC);

  ////System.out.println("SREG="+SREG);

  ////System.out.println("Cycle #="+cycleNum);

 /* for(int i = 0; i<32; i++){

      if(i == 16)

        //System.out.println("|R["+i+"]="+regFile[i]);

     else

       //System.out.print("|R["+i+"]="+regFile[i]);

    }

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

  switch(instr & 0xf000){

 

 

    case 0x1000:

      //ADC (ROL is a special case of this instruction and is not

      //implemented separately

      if((getBit(instr, 11)) && (getBit(instr, 10))){

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

        //Check the C flag for carry

        byte temp = 0;

        if (getBit(regFileIO[0x3f],0))

          temp = (byte)1;

 

        //Get the result of the addition

        R = (byte)(regFile[Rd] + regFile[Rr] + temp);

 

        //Update SREG

        regFileIO[0x3f]=setBit(regFileIO[0x3f],5,(getBit(regFile[Rd],3) & getBit(regFile[Rr],3)) |

                      (getBit(regFile[Rd],3) & !(getBit(R,3))) |

                      (getBit(regFile[Rr],3) & !(getBit(R,3))));

 

        regFileIO[0x3f]=setBit(regFileIO[0x3f],3,(getBit(regFile[Rd],7)&getBit(regFile[Rr],7)&!(getBit(R,7))) |

                      (!getBit(regFile[Rd],7)&!getBit(regFile[Rr],7)&(getBit(R,7))));

        regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

        regFileIO[0x3f]=setBit(regFileIO[0x3f],1,R == (byte) 0);

        regFileIO[0x3f]=setBit(regFileIO[0x3f],0,(getBit(regFile[Rd],7) & getBit(regFile[Rr],7)) |

                      (getBit(regFile[Rd],7) & !(getBit(R,7))) |

                      (getBit(regFile[Rr],7) & !(getBit(R,7))));

        regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

 

        //Store the result in register Rd

        regFile[Rd] = R;

 

       //Increment program counter

       PC++;

       }

 

       //CP

       if((instr & 0x0c00) == 0x0400){

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

        //Compare the registers

        R = (byte)(regFile[Rd] - regFile[Rr]);

        //Update SREG

        regFileIO[0x3f]=setBit(regFileIO[0x3f],5,((!getBit(regFile[Rd],3))&getBit(regFile[Rr],3)) |

                       (getBit(regFile[Rr],3) & getBit(R,3)) |

                       (getBit(R,3) &(!getBit(regFile[Rd],3))));

 

        regFileIO[0x3f]=setBit(regFileIO[0x3f],3,(getBit(regFile[Rd],7) & (!getBit(regFile[Rr],7)) & (!getBit(R,7)) )  |

                      ((!getBit(regFile[Rd],7)) & getBit(regFile[Rr],7) & getBit(R,7) ) );

        regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

        regFileIO[0x3f]=setBit(regFileIO[0x3f],1, R == 0);

        regFileIO[0x3f]=setBit(regFileIO[0x3f], 0, ((!getBit(regFile[Rd], 7)) & getBit(R,7)) |

                        (getBit(R,7) & getBit(regFile[Rr],7)) |

                        (getBit(R,7) & (!getBit(regFile[Rd],7))) );

        regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^getBit(regFileIO[0x3f],3));

        //Increment PC

        PC++;

       }

 

       //CPSE

       if((instr & 0x0c00) == 0x0000){

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

        //Skip next instr if Rd = Rr

        if(regFile[Rd] == regFile[Rr])

          skip = true;

        //Update PC

        PC++;

       }

 

       //Sub

       if(getBit(instr,11) &!getBit(instr,10)){

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

        //Subtract two registers

        R = (byte)(regFile[Rd] - regFile[Rr]);

        //Update SREG

        regFileIO[0x3f]=setBit(regFileIO[0x3f],5,((!getBit(regFile[Rd],3)) & getBit(regFile[Rr],3)) |

                      (getBit(regFile[Rr],3) & getBit(R,3)) |

                      (getBit(R,3) & (!getBit(regFile[Rd],3))));

 

         regFileIO[0x3f]=setBit(regFileIO[0x3f],3,(getBit(regFile[Rd],7) & (!getBit(regFile[Rr],7)) & (!getBit(R,7)) )  |

                      ((!getBit(regFile[Rd],7)) & getBit(regFile[Rr],7) & getBit(R,7) ) );

        regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

        regFileIO[0x3f]=setBit(regFileIO[0x3f],1, R == 0);

        regFileIO[0x3f]=setBit(regFileIO[0x3f], 0, ((!getBit(regFile[Rd], 7)) & getBit(R,7)) |

                        (getBit(R,7) & getBit(regFile[Rr],7)) |

                        (getBit(R,7) & (!getBit(regFile[Rd],7))) );

         regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^getBit(regFileIO[0x3f],3));

        //Place result in Rd

        regFile[Rd] = R;

        //Update PC

        PC++;

       }

 

    break;

 

    case 0x0000:

    //ADD (LSL is a spcial case of this instruction

    if((getBit(instr, 11)) && (getBit(instr, 10))){

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

      R = (byte) (regFile[Rd] + regFile[Rr]);

    //Update SREG

        regFileIO[0x3f]=setBit(regFileIO[0x3f],5,(getBit(regFile[Rd],3) & getBit(regFile[Rr],3)) |

                      (getBit(regFile[Rd],3) & !(getBit(R,3))) |

                      (getBit(regFile[Rr],3) & !(getBit(R,3))));

 

        regFileIO[0x3f]=setBit(regFileIO[0x3f],3,(getBit(regFile[Rd],7)&getBit(regFile[Rr],7)&!(getBit(R,7))) |

                      (!getBit(regFile[Rd],7)&!getBit(regFile[Rr],7)&(getBit(R,7))));

        regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

        regFileIO[0x3f]=setBit(regFileIO[0x3f],1,R == (byte) 0);

        regFileIO[0x3f]=setBit(regFileIO[0x3f],0,(getBit(regFile[Rd],7) & getBit(regFile[Rr],7)) |

                      (getBit(regFile[Rd],7) & !(getBit(R,7))) |

                      (getBit(regFile[Rr],7) & !(getBit(R,7))));

        regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

        //Store the result in register Rd

        regFile[Rd] = R;

 

       //Increment program counter

       PC++;

    }

 

    //CPC

    if((!getBit(instr,11))&getBit(instr,10)){

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

    byte temp = 0;

    if(getBit(regFileIO[0x3f],0))

      temp =1;

    R = (byte)(regFile[Rd] - regFile[Rr] - temp);

    //Update SREG

    regFileIO[0x3f]=setBit(regFileIO[0x3f],5,((!getBit(regFile[Rd],3)) & getBit(regFile[Rr],3)) |

                      (getBit(regFile[Rr],3) & (getBit(R,3))) |

                      ((!getBit(regFile[Rd],3)) & (getBit(R,3))));

 

    regFileIO[0x3f]=setBit(regFileIO[0x3f],3,(getBit(regFile[Rd],7)&(!getBit(regFile[Rr],7))&!(getBit(R,7))) |

                  (!getBit(regFile[Rd],7)&getBit(regFile[Rr],7)&(getBit(R,7))));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],1,(R == (byte) 0)& getBit(regFileIO[0x3f],1));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],0,((!getBit(regFile[Rd],7)) & getBit(regFile[Rr],7)) |

                      ((!getBit(regFile[Rd],7)) & (getBit(R,7))) |

                      (getBit(regFile[Rr],7) & (getBit(R,7))));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

    //Increment PC

    PC++;

    }

 

    //NOP

    if(instr == 0){

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

    //Increment PC

    PC++;

    }

    //SBC

    if(getBit(instr,11) & !getBit(instr,10)){

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

      //Subtract with carry

      byte temp = 0;

      if(getBit(regFileIO[0x3f],0))

        temp++;

      R = (byte)(regFile[Rd] - regFile[Rr] - temp);

      //Update SREG

      regFileIO[0x3f]=setBit(regFileIO[0x3f],5, ((!getBit(regFile[Rd],3)) & getBit(regFile[Rr],3)) |

                     (getBit(regFile[Rr],3)&getBit(R,3))|

                     (getBit(R,3) & !getBit(regFile[Rd],3)));

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3, (getBit(regFile[Rd],7) & (!getBit(regFile[Rr],7)) & (!getBit(R,7))) |

                     ((!getBit(regFile[Rd],7)) &getBit(regFile[Rr],7) & getBit(R,7)));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1,(getBit(regFileIO[0x3f],1) & (R==0)));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],0, ((!getBit(regFile[Rd],7)) & getBit(regFile[Rr],7)) |

                     (getBit(regFile[Rr],7)&getBit(R,7))|

                     (getBit(R,7) & !getBit(regFile[Rd],7)));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

      //Place result in Rd

      regFile[Rd] = R;

      //Increment PC

      PC++;

    }

    break;

 

    case 0x9000:

    //ADIW

 

    if((instr & 0x0f00) == 0x0600){

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

      K = (instr & 0x000f) + ((instr & 0x00c0) >>> 2);

      //Correct the Rd field

      Rd = Rd & 0x00000003;

      //Choose one of the upper four register pairs

      Rd = (Rd * 2 )+24;

      //Temporary varoables for performing the operation

      short temp0 = 0;

      short temp1 = 0;

      int result = 0;

 

      //Add the immediate to the register pair

      temp0 = (short)(((short)regFile[Rd])&0x00ff);

      temp1 = (short)((((short)regFile[Rd+1])&0x00ff) << 8);

      result = (int) ((temp0|temp1) + K);

      regFile[Rd] = (byte) (result & 0x000000ff);

      regFile[Rd+1] = (byte) ((result &0x0000ff00) >>> 8);

 

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,(!getBit(regFile[Rd+1],7)) & getBit (result,15));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(result,15));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1,(result == 0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],0,!getBit(result,15) & getBit(temp1,15));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

      //Advance clock by time period since

      //this is a 2-cycle instruction

      cycleNum ++;

 

      //Increment program counter

      PC++;

 

    }

 

     //ASR

    if((instr & 0x0e0f) == 0x0405){

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

      //Get the result of the shift operation

      R = (byte)(((int)regFile[Rd] << 24)>> 25);

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1, R == 0);

      regFileIO[0x3f]=setBit(regFileIO[0x3f],0,getBit(regFile[Rd],0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f], 0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

      //Place result in Rd

      regFile[Rd] = R;

      //Update PC

      PC++;

    }

 

    //BCLR

    //CLC, CLN, CLH, CLS, CLT, CLV, CLZ are special cases of

    //this instruction and are not implemented separately.

    if((instr & 0x0f8f) == 0x0488){

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

      //Update SREG

      regFileIO[0x3f]=setBit(regFileIO[0x3f],s,false);

 

      //Increment program counter

      PC++;

    }

 

    //BSET

    if((instr&0x0f8f) == 0x0408){

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

      //Update SREG

      regFileIO[0x3f]=setBit(regFileIO[0x3f],s,true);

      //Increment program counter

      PC++;

    }

 

    //CBI

    if((instr & 0x0f00) == 0x0800){

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

      //Set the specified bit in I/O register

      A = (byte)((instr&0x00f8) >>> 3);

      regFileIO[A]=setBit(regFileIO[A],b,false);

      //Update PC

      PC++;

      //This instruction takes 2 cycles

      cycleNum++;

    }

 

    //COM

    if((instr & 0x0e0f) == 0x0400){

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

      //Complement the register

      R= (byte)(0xff - regFile[Rd]);

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,false);

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1, R==0);

      regFileIO[0x3f]=setBit(regFileIO[0x3f],0,true);

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

      //Place the result in register Rd

      regFile[Rd] = R;

      //Update PC

      PC++;

    }

 

    //DEC

    if((instr & 0x0e0f) == 0x040a){

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

      //Decrement register Rd

      R = (byte)(regFile[Rd] - 1);

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,(R == 0x7f));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1, (R == 0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^getBit(regFileIO[0x3f],3));

      //Place the result in register Rd

      regFile[Rd] = R;

      //Increment PC

      PC++;

    }

 

    //ICALL

    if(instr == (short)0x9509){

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

      //Update PC

      PC = Z;

      //Store PC +1 in Stack

      SRAM[stackPtr-96] = (byte)(((PC + 1) & 0x0000ff00) >>> 8);

      SRAM[stackPtr-96 - 1] = (byte)(((PC + 1) & 0x0000ff));

      //Update stack pointer

      stackPtr = stackPtr - 2;

      regFileIO[0x3e] = (byte) ((stackPtr & 0x0000ff00) >>> 8);

      regFileIO[0x3d] = (byte) (stackPtr & 0x000000ff);

      //This is a multicycle instruction

      cycleNum = cycleNum + 3;

    }

 

 

    //IJMP

    if(instr == (short)0x9409){

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

    //Update PC

    PC = Z;

    //This is a two cycle instruction

    cycleNum++;

    }

 

    //INC

    if((instr & 0x0e0f)==0x0403){

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

      //Increment register Rd

      R = (byte)(regFile[Rd] + 1);

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,(R == 0x80));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1,(R==0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

      //Store result in Rd

      regFile[Rd] = R;

      //Increment PC

      PC++;

    }

 

    //LD (using X)

    if((instr & 0x0e0f) == 0x000c){

      //System.out.println("LD USING X DIRECT");

      //Load Indirect

      if(X <= 0x001f)

        regFile[Rd] = regFile[X];

      else if(X <= 0x005f)

        regFile[Rd] = regFileIO[X-32];

      else

        regFile[Rd] = SRAM[X-96];

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

    }

    if((instr & 0x0e0f) == 0x000d){

    //System.out.println("LD USING X INDIRECT");

      //Load Indirect

      if(X <= 0x001f)

        regFile[Rd] = regFile[X];

      else if(X <= 0x005f)

        regFile[Rd] = regFileIO[X-32];

      else

        regFile[Rd] = SRAM[X-96];

      //Post Increment X

      X++;

      regFile[27] = (byte)((X &0x0000ff00) >>> 8);

      regFile[26] = (byte)((X&0x000000ff));

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

    }

     if((instr & 0x0e0f) == 0x000e){

     //System.out.println("LD USING X PRE DEC");

      //Pre Decrement X

      X--;

      //Load Indirect

      if(X <= 0x001f)

        regFile[Rd] = regFile[X];

      else if(X <= 0x005f)

        regFile[Rd] = regFileIO[X-32];

      else

        regFile[Rd] = SRAM[X-96];

      regFile[27] = (byte)((X &0x0000ff00) >>> 8);

      regFile[26] = (byte)((X&0x000000ff));

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

    }

 

    //LD/LDD (Using Y)

 

    if((instr & 0x0e0f) == 0x0009){

    //System.out.println("LD/LDD USING Y INDIRECT");

      //Load Indirect

      if(Y <= 0x001f)

        regFile[Rd] = regFile[Y];

      else if(Y <= 0x005f)

        regFile[Rd] = regFileIO[Y-32];

      else

        regFile[Rd] = SRAM[Y-96];

      //Post Increment Y

      Y++;

      regFile[29] = (byte)((Y &0x0000ff00) >>> 8);

      regFile[28] = (byte)((Y &0x000000ff));

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

    }

    if((instr & 0x0e0f) == 0x000a){

    //System.out.println("LD/LDD USING Y PRE DEC");

      //Pre Decrement Y

      Y--;

      //Load Indirect

      if(Y <= 0x001f)

        regFile[Rd] = regFile[Y];

      else if(Y <= 0x005f)

        regFile[Rd] = regFileIO[Y-32];

      else

        regFile[Rd] = SRAM[Y-96];

      regFile[29] = (byte)((Y &0x0000ff00) >>> 8);

      regFile[28] = (byte)((Y &0x000000ff));

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

    }

 

    //LD/LDD using Z

    if((instr & 0x0e0f) == 0x0001){

      //System.out.println("LD/LDD USING Z INDIRECT");

      //Load Indirect

      if(Z <= 0x001f)

        regFile[Rd] = regFile[Z];

      else if(Z <= 0x005f)

        regFile[Rd] = regFileIO[Z-32];

      else

        regFile[Rd] = SRAM[Z-96];

      //Post Increment Z

      Z++;

      //System.out.println("Z iS=" + Z + "===========================");

      //System.out.println("SRAM[Z]="+SRAM[Z]);

      regFile[31] = (byte)((Z &0x0000ff00) >>> 8);

      regFile[30] = (byte)((Z &0x000000ff));

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

    }

 

    if((instr & 0x0e0f) == 0x0002){

    //System.out.println("LD/LDD USING Z PRE DEC");

      //Pre Decrement Z

      Z--;

 

      //Load Indirect

       if(Z <= 0x001f)

        regFile[Rd] = regFile[Z];

      else if(Z <= 0x005f)

        regFile[Rd] = regFileIO[Z-32];

      else

        regFile[Rd] = SRAM[Z-96];

      regFile[31] = (byte)((Z &0x0000ff00) >>> 8);

      regFile[30] = (byte)((Z &0x000000ff));

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

    }

 

    //LDS

    if((instr & 0x0e0f) == 0x0000){

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

      //Get the lower half of the instruction

      PC++;

      instr = FLASH[PC];

      k = ((int)instr) & 0x0000ffff;

      //Load data into register Rd

       if(k <= 0x001f)

        regFile[Rd] = regFile[k];

      else if(k <= 0x005f)

        regFile[Rd] = regFileIO[k-32];

      else

        regFile[Rd] = SRAM[k-96];

      //Update PC

      PC++;

      //2 cycle instruction

      cycleNum++;

 

    }

 

    //LPM

    if(instr == (short)0x95c8){

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

      //Load the byte into register 0

      short temp = (FLASH[(Z &0x0000fffe)>>>1]);

      if(getBit(Z,0))

      temp = (short)(temp >>> 8);

      regFile[0] = (byte)temp;

      //Increment PC

      PC++;

      //3 cycle instruction

      cycleNum = cycleNum +2;

    }

    if((instr&0xfe0f) == (short)0x9004){

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

      //Load the byte into register 0

      short temp = (FLASH[(Z &0x0000fffe)>>>1]);

      if(getBit(Z,0))

      temp = (short)(temp >>> 8);

      regFile[Rd] = (byte)temp;

      //Increment PC

      PC++;

      //3 cycle instruction

      cycleNum = cycleNum +2;

    }

    if((instr&0xfe0f) == (short)0x9005){

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

      //Load the byte into register 0

      short temp = (FLASH[(Z &0x0000fffe)>>>1]);

      if(getBit(Z,0))

      temp = (short)(temp >>> 8);

      regFile[Rd] = (byte)temp;

        //Post Increment

        Z++;

        regFile[31] = (byte)((Z &0x0000ff00) >>> 8);

        regFile[30] = (byte)((Z &0x000000ff));

      //Increment PC

      PC++;

      //3 cycle instruction

      cycleNum = cycleNum +2;

    }

 

    //LSR

    if((instr & 0x0e0f) == 0x0406){

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

      //Get the result of the shift operation

      R = (byte)((regFile[Rd]&0x000000ff) >>> 1);

 

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,false);

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1, R == 0);

      regFileIO[0x3f]=setBit(regFileIO[0x3f],0,getBit(regFile[Rd],0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f], 0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

 

      //Place the result in Rd

      regFile[Rd] = R;

      //Update PC

      PC++;

    }

 

    //NEG

    if((instr&0x0e0f) == 0x0401){

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

      //Take the two's complement of Rd

      R = (byte)(0 - regFile[Rd]);

      //Update SREG

      regFileIO[0x3f]=setBit(regFileIO[0x3f],5,getBit(R,3) | getBit(regFile[Rd],3));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,(R == 0x80));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1,(R == 0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],0,(R !=0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

      //Store the result in Rd

      regFile[Rd] = R;

      //Update PC

      PC++;

    }

 

    //POP

    if((instr &0x0e0f)==0x000f){

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

      //Incremet SP

      stackPtr++;

      regFileIO[0x3e] = (byte)((stackPtr & 0x0000ff00)>>>8);

      regFileIO[0x3d] = (byte)(stackPtr & 0x000000ff);

      //Pop the Stack

      regFile[Rd] = SRAM[stackPtr-96];

      //2-cycle instruction

      cycleNum++;

      //Increment PC

      PC++;

    }

 

    //Push

    if((instr &0x0e0f)==0x020f){

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

      //Pop the Stack

       SRAM[stackPtr-96] = regFile[Rd];

      //Incremet SP

      stackPtr--;

      regFileIO[0x3e] = (byte)((stackPtr & 0x0000ff00)>>>8);

      regFileIO[0x3d] = (byte)(stackPtr & 0x000000ff);

      //2-cycle instruction

      cycleNum++;

      //Increment PC

      PC++;

    }

 

    //RET

    if(instr == (short)0x9508){

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

      //Update PC

      PC = 0x00000000 | ((int)SRAM[stackPtr-96+1]&0x000000ff);

      PC = PC | ((((int)SRAM[stackPtr-96+2]) &0x000000ff) << 8);

      //Update SP

      stackPtr = stackPtr + 2;

      regFileIO[0x3e] = (byte)((stackPtr & 0x0000ff00)>>>8);

      regFileIO[0x3d] = (byte)(stackPtr & 0x000000ff);

      //4-cycle instruction

      cycleNum = cycleNum + 3;

    }

 

    //RETI

    if(instr == (short)0x9518){

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

     //Update PC

      //PC = 0x00000000 | SRAM[stackPtr+1];

      //PC = PC | ((((int)SRAM[stackPtr]) &0x0000000f) << 8);

      //System.out.println("STACKPTR="+stackPtr);

      PC = 0x00000000 | ((int)SRAM[stackPtr-96+1]&0x000000ff);

      PC = PC | ((((int)SRAM[stackPtr-96+2]) &0x000000ff) << 8);

      //Update SP

      stackPtr = stackPtr + 2;

      regFileIO[0x3e] = (byte)((stackPtr & 0x0000ff00)>>>8);

      regFileIO[0x3d] = (byte)(stackPtr & 0x000000ff);

      //4-cycle instruction

      cycleNum = cycleNum + 3;

      //Update SREG

      regFileIO[0x3f]=setBit(regFileIO[0x3f],7,true);

    }

 

    //ROR

    if((instr & 0x0e0f) == 0x0407){

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

      //Rotate right through carry

      R = (byte)((regFile[Rd] & 0x000000ff)>>> 1);

      R = setBit(R,7,getBit(regFileIO[0x3f],0));

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1,R==0);

      regFileIO[0x3f]=setBit(regFileIO[0x3f],0,getBit(regFile[Rd],0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],3) ^ getBit(regFileIO[0x3f],2));

      //Place result in Rd

      regFile[Rd] = R;

      //Increment PC

      PC++;

    }

 

    //SBI

    if((instr&0x0f00) == 0x0a00){

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

      //Set bit in I/O register

      A = (byte)((instr&0x00f8) >>> 3);

      regFileIO[A]=setBit(regFileIO[A],b,true);

      //2 cycle instruction

      cycleNum++;

      //increment PC

      PC++;

    }

 

    //SBIC

    if((instr&0x0f00) == 0x0900){

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

    //Skip if bit ion I/O register cleared

    A = (byte)((instr&0x00f8) >>> 3);

    if(!getBit(regFileIO[A],b))

      skip = true;

    //Increment PC

    PC++;

    }

 

 

    //SBIS

    if((instr&0x0f00) == 0x0b00){

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

    //Skip if bit ion I/O register cleared

    A = (byte)((instr&0x00f8) >>> 3);

    if(getBit(regFileIO[A],b))

      skip = true;

    //Increment PC

    PC++;

    }

 

 

    //SBIW

    if((instr & 0x0f00) == 0x0700){

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

    //Correct the Rd field

      Rd = Rd & 0x00000003;

      //Choose one of the upper four register pairs

      Rd = (Rd * 2 )+24;

      //Get the correct K field

      K = (((instr & 0x00c0) >>> 2) |(instr &0x000f));

      //Temporary variables for getting the two bytes

      byte temp0 = regFile[Rd];

      byte temp1 = regFile[Rd+1];

      short result = 0;

      result = (short)((((result | temp1)&0x00ff) << 8 ) | (((short)temp0)&0x00ff));

      //Subtract imediate from word

      result = (short)(result - (short)K);

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,!getBit(result,15) & getBit(regFile[Rd+1],7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(result,15));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1,result==0);

      regFileIO[0x3f]=setBit(regFileIO[0x3f],0,getBit(result,15) & !getBit(regFile[Rd+1],7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],3) ^ getBit(regFileIO[0x3f],2));

      //Place result in Rd:Rd+1

      regFile[Rd+1] = (byte) (result>>>8);

      regFile[Rd] = (byte) (result &0x00ff);

      //Update PC

      PC++;

      //2 cycle instruction

      cycleNum++;

 

    }

 

    //SLEEP

    if(instr == (short)0x9588){

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

    //Enter the correct mode

    //Sleep enabled

    if(getBit(regFileIO[0x35],5)){

      pwrDownMode = getBit(regFileIO[0x35],4);

      idleMode = !pwrDownMode;

    }

    //Update PC

    PC++;

    }

 

    //ST (Using index X)

    if((instr&0x0e0f) == 0x020c){

    //System.out.println("ST USING X");

    //Get the correct value of Rr

    Rr = (instr & 0x000001f0)>>>4;

    if(X <= 0x001f)

      regFile[X] = regFile[Rr];

    else if(X <= 0x005f)

      regFileIO[X-32] = regFile[Rr];

    else

      SRAM[X-96] = regFile[Rr];

    //Increment PC

    PC++;

    //2 cycle instruction

    cycleNum++;

    }

    if((instr&0x0e0f) == 0x020d){

    //System.out.println("ST USING X POST INC");

    Rr = (instr & 0x000001f0)>>>4;

      if(X <= 0x001f)

       regFile[X] = regFile[Rr];

      else if(X <= 0x005f)

        regFileIO[X-32] = regFile[Rr];

      else

      SRAM[X-96] = regFile[Rr];

      X++;

      regFile[27] = (byte)((X &0x0000ff00) >>> 8);

      regFile[26] = (byte)((X&0x000000ff));

      //2 cycle instruction

      cycleNum++;

      //Increment PC

      PC++;

    }

    if((instr&0x0e0f) == 0x020e){

    //System.out.println("ST USING X PRE DEC");

    Rr = (instr & 0x000001f0)>>>4;

      //Pre decrement X

      X--;

      if(X <= 0x001f)

        regFile[X] = regFile[Rr];

      else if(X <= 0x005f)

        regFileIO[X-32] = regFile[Rr];

      else

        SRAM[X-96] = regFile[Rr];

      regFile[27] = (byte)((X &0x0000ff00) >>> 8);

      regFile[26] = (byte)((X&0x000000ff));

      //2 cycle instruction

      cycleNum++;

      //Increment PC

      PC++;

    }

 

    //ST (using Y)

    if((instr&0x0e0f) ==0x0209){

    //System.out.println("ST USING Y POST INCREMENT");

    Rr = (instr & 0x000001f0)>>>4;

    //Store Indirect

    if(Y <= 0x001f)

      regFile[Y] = regFile[Rr];

    else if(Y <= 0x005f)

      regFileIO[Y-32] = regFile[Rr];

    else

      SRAM[Y-96] = regFile[Rr];

    //Post increment

    Y++;

    regFile[29] = (byte)((Y &0x0000ff00) >>> 8);

    regFile[28] = (byte)((Y &0x000000ff));

    //Increment PC

    PC++;

    //2 cycle instruction

    cycleNum++;

    }

 

    if((instr&0x0e0f) ==0x020a){

    //System.out.println("ST USING Y PRE DECREMENT");

    Rr = (instr & 0x000001f0)>>>4;

    //Pre decrement

    Y--;

    //Store Indirect

     if(Y <= 0x001f)

      regFile[Y] = regFile[Rr];

    else if(Y <= 0x005f)

      regFileIO[Y-32] = regFile[Rr];

    else

      SRAM[Y-96] = regFile[Rr];

    regFile[29] = (byte)((Y &0x0000ff00) >>> 8);

    regFile[28] = (byte)((Y &0x000000ff));

    //Increment PC

    PC++;

    //2 cycle instruction

    cycleNum++;

    }

 

    //ST (Using Z)

    if((instr&0x0e0f)==0x0201){

    //System.out.println("ST USING Z POST INCREMENT");

    Rr = (instr & 0x000001f0)>>>4;

    //Store Indirect

     if(Z <= 0x001f)

      regFile[Z] = regFile[Rr];

    else if(Z <= 0x005f)

      regFileIO[Z-32] = regFile[Rr];

    else

      SRAM[Z-96] = regFile[Rr];

    //Post increment

    Z++;

    regFile[31] = (byte)((Z &0x0000ff00) >>> 8);

    regFile[30] = (byte)((Z &0x000000ff));

    //Increment PC

    PC++;

    //2 cycle instruction

    cycleNum++;

    }

    if((instr&0x0e0f)==0x0202){

    //System.out.println("ST USING Z PRE DECREMENT");

    Rr = (instr & 0x000001f0)>>>4;

    //Pre decrement

    Z--;

    //Store Indirect

     if(Z <= 0x001f)

      regFile[Z] = regFile[Rr];

    else if(Z <= 0x005f)

      regFileIO[Z-32] = regFile[Rr];

    else

      SRAM[Z-96] = regFile[Rr];

    regFile[31] = (byte)((Z &0x0000ff00) >>> 8);

    regFile[30] = (byte)((Z &0x000000ff));

    //Increment PC

    PC++;

    //2 cycle instruction

    cycleNum++;

    }

 

    //STS

    if((instr & 0x0e0f) == 0x0200){

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

      //Get the lower half of the instruction

      PC++;

      instr = FLASH[PC];

      k = ((int)instr) & 0x0000ffff;

      //Store data into SRAm

       if(k <= 0x001f)

      regFile[k] = regFile[Rr];

      else if(k <= 0x005f)

      regFileIO[k-32] = regFile[Rr];

      else

      SRAM[k-96] = regFile[Rr];

      //Update PC

      PC++;

      //2 cycle instruction

      cycleNum++;

 

    }

 

    //SWAP

    if((instr&0x0e0f)==0x0402){

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

      //SWAP the nibbles

      byte temp = (byte)((regFile[Rd]>>>4) & 0x0f);

      regFile[Rd] = (byte)((regFile[Rd]<<4) | temp);

      //Update PC

      PC++;

    }

 

    //WDR

    if(instr == (short)0x95a8){

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

      //Reset WatchDog timer

      wReset = true;

      //Update PC

      PC++;

    }

    break;

 

 

 

    case 0x8000:

      //LDD using Y

      if((!getBit(instr,9)) &getBit(instr,3)){

      //System.out.println("LDD USING Y DISPLACEMENT");

      //Load with displacement

       if(Y+q <= 0x001f)

        regFile[Rd] = regFile[Y+q];

      else if(Y+q <= 0x005f)

        regFile[Rd] = regFileIO[Y+q-32];

      else

        regFile[Rd] = SRAM[Y+q-96];

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

      }

 

      //LDD using Z

      if((!getBit(instr,9)) &(!getBit(instr,3))){

      //System.out.println("LDD USING Z DISPLACEMENT");

      //Load with displacement

       if(Z+q <= 0x001f)

        regFile[Rd] = regFile[Z+q];

      else if(Z+q <= 0x005f)

        regFile[Rd] = regFileIO[Z+q-32];

      else

        regFile[Rd] = SRAM[Z+q-96];

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

      }

 

      //STD using Y

      if(getBit(instr,9)&getBit(instr,3)){

      //System.out.println("STD USING Y INDIRCET");

      //Get the correct value of Rr

      Rr = (instr & 0x000001f0)>>>4;

        //Store Indirect

        if(Y+q <= 0x001f)

        regFile[Y+q] = regFile[Rr];

        else if(Y+q <= 0x005f)

        regFileIO[Y+q-32] = regFile[Rr];

        else

        SRAM[Y+q-96] = regFile[Rr];

        //Update PC

        PC++;

        //2 cycle instruction

        cycleNum++;

      }

 

      //STD using Z

      if((instr & 0x8208)==0x8200){

      //System.out.println("STD USING Z INDIRECT");

      Rr = (instr & 0x01f0)>>>4;

        //Store Indirect

        if(Z+q <= 0x001f)

        regFile[Z+q] = regFile[Rr];

        else if(Z+q <= 0x005f)

        regFileIO[Z+q-32] = regFile[Rr];

        else

        SRAM[Z+q-96] = regFile[Rr];

        //Update PC

        PC++;

        //2 cycle instruction

        cycleNum++;

      }

    break;

 

    case 0xa000:

    //LDD using Y

      if((!getBit(instr,9)) &getBit(instr,3)){

      //System.out.println("LDD USING Y DISPLACEMENT");

      //Load with displacement

       if(Y+q <= 0x001f)

        regFile[Rd] = regFile[Y+q];

      else if(Y+q <= 0x005f)

        regFile[Rd] = regFileIO[Y+q-32];

      else

        regFile[Rd] = SRAM[Y+q-96];

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

      }

 

      //LDD using Z

      if((!getBit(instr,9)) &(!getBit(instr,3))){

      //System.out.println("LDD USING Z DISPLACEMENT");

      //Load with displacement

       if(Z+q <= 0x001f)

        regFile[Rd] = regFile[Z+q];

      else if(Z+q <= 0x005f)

        regFile[Rd] = regFileIO[Z+q-32];

      else

        regFile[Rd] = SRAM[Z+q-96];

      //increment PC

      PC++;

      //2 cycle Instruction

      cycleNum++;

      }

 

      //STD using Y

      if(getBit(instr,9)&getBit(instr,3)){

      //System.out.println("STD USING Y INDIRECT");

      //Get the correct value of Rr

      Rr = (instr & 0x000001f0)>>>4;

        //Store Indirect

        if(Y+q <= 0x001f)

        regFile[Y+q] = regFile[Rr];

        else if(Y+q <= 0x005f)

        regFileIO[Y+q-32] = regFile[Rr];

        else

        SRAM[Y+q-96] = regFile[Rr];

        //Update PC

        PC++;

        //2 cycle instruction

        cycleNum++;

      }

 

      //STD using Z

      if(getBit(instr,9)&!getBit(instr,3)){

      //System.out.println("STD USING Z INDIRECT");

      //Get the correct value of Rr

      Rr = (instr & 0x000001f0)>>>4;

        //Store Indirect

        if(Z+q <= 0x001f)

        regFile[Z+q] = regFile[Rr];

        else if(Z+q <= 0x005f)

        regFileIO[Z+q-32] = regFile[Rr];

        else

        SRAM[Z+q-96] = regFile[Rr];

        //Update PC

        PC++;

        //2 cycle instruction

        cycleNum++;

      }

    break;

 

    case 0x2000:

    //AND

    if((!getBit(instr,11)) & (!getBit(instr,10))){

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

      //Get the result of the the and operation

      R = (byte) (regFile[Rd] & regFile[Rr]);

 

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,false);

      regFileIO[0x3f]=setBit(regFileIO[0x3f], 2, getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f], 1, (R == 0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

      //Place the result in register Rd

      regFile[Rd] = R;

 

      //Increment program counter

      PC++;

    }

 

    //EOR

    if((!getBit(instr,11))&getBit(instr,10)){

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

      //Exor the destination and source registers

      R = (byte) (regFile[Rd] ^ regFile[Rr]);

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,false);

      regFileIO[0x3f]=setBit(regFileIO[0x3f], 2, getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f], 1, (R == 0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

      //Update PC

      PC++;

      //Place the result in Rd

      regFile[Rd] = R;

      }

 

    //MOV

    if(getBit(instr,11)&getBit(instr,10)){

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

      //copy Rr to Rd

      regFile[Rd] = regFile[Rr];

      //increment PC

      PC++;

    }

 

    //OR

    if(getBit(instr,11) & !getBit(instr,10)){

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

      //OR Rd and Rr

      R = (byte)(regFile[Rd] | regFile[Rr]);

      //Update SREG

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3,false);

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1,(R == 0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

      //Place the result in Rd

      regFile[Rd] = R;

      //Increment PC

      PC++;

    }

    break;

 

    case 0x7000:

    //ANDI

    //Get the result of the and operation

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

    Rd = 16 + (setBit(Rd,4,false));

    R  = (byte)((byte)K & regFile[Rd]);

 

    //Update SREG

 

    regFileIO[0x3f]=setBit(regFileIO[0x3f],3,false);

    regFileIO[0x3f]=setBit(regFileIO[0x3f], 2, getBit(R,7));

    regFileIO[0x3f]=setBit(regFileIO[0x3f], 1, (R == 0));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

    //Place the result in register Rd

    regFile[Rd] = R;

 

    //Increment program counter

    PC++;

    break;

 

    case 0xf000:

    //BLD

    if((instr & 0x0e08) == 0x0800){

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

      //Set register Rd to the value of the T flag

      regFile[Rd]=setBit(regFile[Rd],b,getBit(regFileIO[0x3f],6));

      //Update program counter

      PC++;

    }

 

    //BRBC

    //(BRCC,BRTC,BRSH, BRID, BRHC, BRNE, BRPL, BRGE and BRVC are special cases of this

    //instruction and is not implemented separately)

    if((!getBit(instr,11)) & getBit(instr,10)){

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

      //Get the correct value of k

      k = (((int) ((instr >>> 3) & 0x007f)) << 25) >> 25;

      //Get bit number in SREG

      s = instr & 0x0007;

      //Branch if regFileIO[0x3f](s) = 0

      if(!getBit(regFileIO[0x3f],s)){

        PC = PC + 1 + k;

        //Instruction takes 2 cycles if condition is true

        cycleNum++;

        }

      else

        PC++;

    }

 

     //BRBS

     //(BRCS, BRTS,BRVS, BRLO, BRIE,BRHS, BREQ, BRMI, BRLT are special cases of this instruction

     //and are not implemented separately)

    if((!getBit(instr,11)) & (!getBit(instr,10))){

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

      //Get the correct value of k

      k= (((int) ((instr >>> 3) & 0x007f)) << 25) >> 25;

      //Get bit number in SREG

      s = instr & 0x0007;

      //Branch if SREG(s) = 1

      if(getBit(regFileIO[0x3f],s)){

        PC = PC + 1 + k;

        //instruction takes two cycles if condition is true

        cycleNum++;

      }

      else

        PC++;

    }

 

    //BST

    if((instr & 0x0e08)==0x0a00){

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

      //Update SREG

      regFileIO[0x3f]=setBit(regFileIO[0x3f],6,getBit(regFile[Rd],b));

      //Increment program counter

      PC++;

    }

 

    //SBRC

    if((instr & 0x0e08)==0x0c00){

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

    //Get the correct value of Rr

    Rr = (instr & ((short)0x01f0)) >>> 4;

      //skip if bit in register is cleared

      if(!getBit(regFile[Rr],b))

        skip = true;

      //Update PC

      PC++;

    }

 

    //SBRS

    if((instr & 0x0e08)==0x0e00){

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

    //Get the correct value of Rr

    Rr = (instr & ((short)0x01f0)) >>> 4;

      //skip if bit in register is cleared

      if(getBit(regFile[Rr],b))

        skip = true;

      //Update PC

      PC++;

    }

    break;

 

    case 0x3000:

      //CPI

      //Compare with Immediate

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

      //Get the correct value of Rd

      Rd = 16 + setBit(Rd,4,false);

      R = (byte) (regFile[Rd] - K);

      //Update SREG

      regFileIO[0x3f]=setBit(regFileIO[0x3f],5, ( (!getBit(regFile[Rd],3)) & getBit(K,3)) |

                        (getBit(K,3) & getBit(R,3)) |

                        (getBit(R,3) & (!getBit(regFile[Rd] ,3))) );

 

      regFileIO[0x3f]=setBit(regFileIO[0x3f],3, (getBit(regFile[Rd],7) & (!getBit(K,7)) & (!getBit(R,7))) |

                      (!getBit(regFile[Rd],7) & getBit(K,7) & getBit(R,7)));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],1, (R == 0));

      regFileIO[0x3f]=setBit(regFileIO[0x3f],0, ((!getBit(regFile[Rd],7)) & getBit(K,7)) |

                      (getBit(K,7) & getBit(R,7)) |

                      (getBit(R,7) & (!getBit(regFile[Rd],7))) );

      regFileIO[0x3f]=setBit(regFileIO[0x3f] , 4 , getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

 

      //Increment PC

      PC++;

    break;

 

    case 0xb000:

    //IN

    if(!getBit(instr,11)){

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

    //Get the correct I/O address

    A = ((instr & 0x0600) >>> 5) | (instr &0x000f);

    //Load data from I/O space

    regFile[Rd] = regFileIO[A];

    //Increment PC

    PC++;

    }

 

    //OUT

    if(getBit(instr,11)){

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

    //Get the correct value of Rr

    Rr = (instr&0x01f0) >>>4;

    //Get the correct I/O address

    A = ((instr & 0x0600) >>> 5) | (instr &0x000f);

    //Load data to I/O space

    regFileIO[A] = regFile[Rr];

    /////////////////////////////////*********DEBUG***************

//    //System.out.println("RegFileIO["+A+"]="+regFile[Rr]);

    if(A== 0x32){

      //System.out.println("***************************SETTING TCNT0 to "+ regFile[Rr]);

      }

    //////////////////////////////////////////////////////////////

    //Increment PC

    PC++;

    }

    break;

 

    case 0xe000:

    //LDI (SER is a special case of this instruction)

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

    Rd = 16+((instr &0x00f0) >>> 4);

    regFile[Rd] = (byte)K;

    //Increment PC

    PC++;

    break;

 

    case 0x6000:

    //ORI (SBR is a special case of this instruction)

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

    //Get the correct Rd

    Rd = ((instr & 0x00f0) >> 4) + 16;

 

    //Get the result of the operation

    R = (byte)(regFile[Rd] | K );

 

    //Update SREG

 

    regFileIO[0x3f]=setBit(regFileIO[0x3f],3,false);

    regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],1,(R==0));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

    //place the result in Rd

    regFile[Rd] = R;

    //Increment PC

    PC++;

 

    break;

 

    case 0xd000:

    //RCALL

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

    //System.out.println("STACKPTR="+stackPtr);

    //get the correct value of k

    k = ((int)(instr & 0x0fff) <<20)>>20;

    //System.out.println("k="+k);

    //Store PC +1 in Stack

      SRAM[stackPtr-96] = (byte)(((PC + 1 ) & 0x0000ff00) >>> 8);

      ////System.out.println(SRAM[stackPtr]);

      SRAM[stackPtr-96 - 1] = (byte)(((PC + 1 ) & 0x0000ff));

      //Update stack pointer

      stackPtr = stackPtr - 2;

      regFileIO[0x3e] = (byte) ((stackPtr & 0x0000ff00) >>> 8);

      regFileIO[0x3d] = (byte) (stackPtr & 0x000000ff);

    //Update PC

    PC = PC +k +1;

    //3-cycle instruction

    cycleNum = cycleNum + 2;

    break;

 

    case 0xc000:

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

    //RJMP

    //Get the correct k

    k = ((instr & 0x0fff)<<20)>>20;

    //Update PC

    PC = PC + k + 1;

    //2-cycle instruction

    cycleNum++;

    break;

 

    //SBCI

    case 0x4000:

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

    //Get the correct Rd

    Rd = 16 + (Rd & 0x0000000f);

    //Subtract immediate with carry

    byte temp = 0;

    if(getBit(regFileIO[0x3f],0))

      temp++;

    R = (byte)(regFile[Rd] - K - temp);

    //Update SREG

    regFileIO[0x3f]=setBit(regFileIO[0x3f],5, ((!getBit(regFile[Rd],3)) & getBit(K,3)) |

                   (getBit(K,3) & getBit(R,3)) |

                   (getBit(R,3) & !getBit(regFile[Rd],3)));

 

    regFileIO[0x3f]=setBit(regFileIO[0x3f],3, ((getBit(regFile[Rd],7)) & getBit(K,7) & !getBit(R,7)) |

                   (getBit(K,7) & getBit(R,7) & !getBit(regFile[Rd],7)));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

    regFileIO[0x3f]=setBit(regFileIO[0x3f], 1, (R == 0) & getBit(regFileIO[0x3f],1));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],0, ((!getBit(regFile[Rd],7)) & getBit(K,7)) |

                   (getBit(K,7) & getBit(R,7)) |

                   (getBit(R,7) & !getBit(regFile[Rd],7)));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

    //Place result in Rd

    regFile[Rd] = R;

    //Increment PC

    PC++;

    break;

 

    case 0x5000:

    //SUBI

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

    //Get the correct Rd

    Rd =16 +( Rd & 0x0000000f);

    R = (byte)((((int)regFile[Rd])&0x000000ff) - K);

 

    //Update SREG

    regFileIO[0x3f]=setBit(regFileIO[0x3f],5, ((!getBit(regFile[Rd],3)) & getBit(K,3)) |

                   (getBit(K,3) & getBit(R,3)) |

                   (getBit(R,3) & !getBit(regFile[Rd],3)));

 

    regFileIO[0x3f]=setBit(regFileIO[0x3f],3, ((getBit(regFile[Rd],7)) & getBit(K,7) & !getBit(R,7)) |

                   (getBit(K,7) & getBit(R,7) & !getBit(regFile[Rd],7)));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],2,getBit(R,7));

    regFileIO[0x3f]=setBit(regFileIO[0x3f], 1, (R == 0));

    regFileIO[0x3f]=setBit(regFileIO[0x3f],0, ((!getBit(regFile[Rd],7)) & getBit(K,7)) |

                   (getBit(K,7) & getBit(R,7)) |

                   (getBit(R,7) & !getBit(regFile[Rd],7)));

     regFileIO[0x3f]=setBit(regFileIO[0x3f],4,getBit(regFileIO[0x3f],2) ^ getBit(regFileIO[0x3f],3));

    //Place result in Rd

    regFile[Rd] = R;

    //Increment PC

    PC++;

    break;

 

    }//END SWITCH

 

 //Increment Cycle Number

  cycleNum++;

  //Check if a branch succeeded

  if(skip){

    skip = false;

    if(((short)(FLASH[PC] & (short)0xfe0f) == (short)0x9000)|

       ((short)(FLASH[PC] & (short)0xfe0f) == (short)0x9200)){

       cycleNum = cycleNum + 2;

       PC = PC + 2;

       }

    else{

      cycleNum++;

      PC++;

    }

  }

   //*******************TIMER1**********************************///////

    //Get the current TCNT1

    TCNT1 =((((int) regFileIO[0x2d]) << 8)&0x0000ff00) | (((int) regFileIO[0x2c]) & 0x000000ff);

    //Detect when TCNT1 begins counting (when pwn mode disabled)

    if((!getBit(regFileIO[0x2f],0))&&(!getBit(regFileIO[0x2f],1))&&((TCNT1Init!=TCNT1)|(TCCR1BInit!=regFileIO[0x2e]))){

      resetCycle1 = cycleNum;

    }

    if(prescaler1!=0){

      if(((cycleNum - resetCycle1)/prescaler1>0)&(TCNT1Init==TCNT1)){

        resetCycle1 = resetCycle1+prescaler1;

      if((cycleNum - cycleNumInit)>prescaler1)

        inc1 = (int)((cycleNum -cycleNumInit)/prescaler1);

      else

        inc1++;

      }

    if((OCR1AHInit!=regFileIO[0x2b])|(regFileIO[0x2a]!=OCR1ALInit)){

      OCR1AWritten =true;

    }

    //PWM Mode Disabled

    if((!getBit(regFileIO[0x2f],0))&&(!getBit(regFileIO[0x2f],1))){

      //Compare 1A Mode Select

      //Set the OC1A output line

      if(getBit(regFileIO[0x11],5)){

        if(getBit(regFileIO[0x2f],7) && getBit(regFileIO[0x2f],6))

          regFileIO[0x12]=setBit(regFileIO[0x12],5,true);

        else if(getBit(regFileIO[0x2f],7)&&!getBit(regFileIO[0x2f],6))

          regFileIO[0x12]=setBit(regFileIO[0x12],5,false);

        else if(!getBit(regFileIO[0x2f],7)&&getBit(regFileIO[0x2f],6))

          regFileIO[0x12]=setBit(regFileIO[0x12],5,!getBit(regFileIO[0x12],5));

      }

      //Compare 1B Mode Select

      //Set the OC1B output line

      if(getBit(regFileIO[0x2f],5) && getBit(regFileIO[0x2f],4))

        OC1B = true;

      else if(getBit(regFileIO[0x2f],5)&&!getBit(regFileIO[0x2f],4))

        OC1B = false;

      else if(!getBit(regFileIO[0x2f],5)&&getBit(regFileIO[0x2f],4))

        OC1B = !OC1B;

 

    }

    //TCNT1 COMPA MATCH

    if(!waitForISR_TCNT1_COMPA){

      waitForISR_TCNT1_COMPA=true;

      regFileIO[0x38]=setBit(regFileIO[0x38],6,true);

      //Check the CTC1 bit

      if(getBit(regFileIO[0x2e],3)&!clrTimer1Set){

       clrTimer1 = true;

      }

      clrTimer1Set = false;

    }

    if((TCNT1Init <= OCR1AInit)&(TCNT1Init+inc1>=OCR1AInit)/*&OCR1AWritten*/){

      if((TCNT1Init+inc1>OCR1AInit)&(getBit(regFileIO[0x2e],3))){

        clrTimer1 = true;

        clrTimer1Set = true;

      }

      waitForISR_TCNT1_COMPA = false;

      //System.out.println("wait_ForISR_TCNT1_COMPA setting to false###################################################");

    }

    //TCNT1 COMPB MATCH

    if(!waitForISR_TCNT1_COMPB){

      regFileIO[0x38]=setBit(regFileIO[0x38],5,true);

    }

    if((regFileIO[0x2d] == regFileIO[0x29]) && (regFileIO[0x2c] == regFileIO[0x28])){

      waitForISR_TCNT1_COMPB = false;

    }

 

 

 

 

 

 

    //System.out.println("inc1 after updating this cycle="+inc1);

    //Handle overflow

    if(!waitForISR_TCNT1_OVF ){

      regFileIO[0x38]=setBit(regFileIO[0x38],7,true);

      waitForISR_TCNT1_OVF  = true;

    }

    if(((0x0000ffff)- (((int)TCNT1Init)&(0x0000ffff))<inc1)&waitForISR_TCNT1_OVF ){

      waitForISR_TCNT1_OVF  = false;

    }

    TCNT1 = TCNT1 + inc1;

    regFileIO[0x2d] = (byte) (TCNT1 >>> 8);

    regFileIO[0x2c] = (byte) TCNT1;

    //Clear Timer 1 if a compare match

    //occurred last cycle and the CTC1

    //bit was set

    if(clrTimer1){

        clrTimer1 = false;

        regFileIO[0x2d] = 0;

        regFileIO[0x2c] = 0;

      }

    }

 

 

 

   //*******************TIMER0**********************************///////

   //Detect when TCNT0 begins counting

    if ((regFileIO[0x32] != TCNT0Init)|((byte)(TCCR0Init&0x07)!=(byte)(regFileIO[0x33]&0x07))){

       resetCycle0 = cycleNum;

        //System.out.println("-----------------------------RESET CYCLE 0 ="+resetCycle0);

    }

     if(!waitForPrescaler0){

      inc0 = 1;

      resetCycle0 = cycleNumInit+1;

      waitForPrescaler0 = true;

    }

    if(((byte)(TCCR0Init&0x07)!=(byte)(regFileIO[0x33]&0x07))){

      waitForPrescaler0 = false;

    }

    if(prescaler0 != 0){

    if(((cycleNum - resetCycle0)/prescaler0>0)&(TCNT0Init==regFileIO[0x32])){

      resetCycle0 = resetCycle0+prescaler0;

      if((cycleNum - cycleNumInit)>prescaler0)

        inc0 = (int)((cycleNum -cycleNumInit)/prescaler0);

      else

        inc0++;

    }

 

    //System.out.println("$$$$$$$$$$$$$$$$$$$$inc0="+inc0);

    //Handle overflow

    if(!waitForISR_TCNT0_OVF ){

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

      regFileIO[0x38]=setBit(regFileIO[0x38],1,true);

      waitForISR_TCNT0_OVF  = true;

    }

    if(((0x000000ff)- (((int)TCNT0Init)&(0x000000ff))<inc0)&waitForISR_TCNT0_OVF ){

      waitForISR_TCNT0_OVF  = false;

    }

    regFileIO[0x32] = (byte)(regFileIO[0x32] + inc0);

  }

    inc1=0;

    inc0=0;

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

  //System.out.println("SREG="+regFileIO[0x3f]);

 /////////////////////////////////////////// }//END WHILE TRUE

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

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

 

}

 

//Overloaded method for getting the desired bit of a byte or short

public boolean getBit(short s, int bitNum){

  short temp = 1;

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

}

 

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);

}

 

 

//Set a single bit of a register.The bit number is

//specified by bitNum, and the value of the bit

//by bitVal.

public byte setBit(byte b , int bitNum, boolean bitVal){

  if (bitVal){

    byte temp  = 1;

    b = (byte) (b | ( temp << bitNum));

  }

  else{

    byte temp = 1;

    temp = (byte) ~(temp << bitNum);

    b = (byte) (b & temp);

    }

  return b;

}

 

public int setBit(int i , int bitNum, boolean bitVal){

  if (bitVal){

    int temp  = 0x1;

    i = (int) (i | ( temp << bitNum));

  }

  else{

    int temp = 1;

    temp = (int) ~(temp << bitNum);

    i = (int) (i & temp);

    }

    return i;

}

 

}

 

Compiler:

package avrsimmx;

 

/**

 * <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);

    }

   // 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 avrsimmx;

 

/**

 * <p>Title: </p>

 * <p>Description: </p>

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

 * <p>Company: </p>

 * @author unascribed

 * @version 1.0

 */

 

public class Element {

  //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;

  }

}

 

HexReader:

package avrsimmx;

 

 

 

/**

 * <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){

 

 

    HexReader hxReader = new HexReader();

    AT90S8515 MCU = new AT90S8515();

    Parser p = new Parser();

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

    //hxReader.loadMEM("itestsinewave.hex",MCU.FLASH);

    hxReader.loadMEM(p.hexFile,MCU.FLASH);

  /*  for(int i=0; i<2700; i++){

 

      MCU.run();

    }*/

    Compiler C = new Compiler();

 

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

/*

    Element[] e = new Element[24];

    e[0] = new Element(C.VSRC,0,1,-1,-1,0,1,0,21);

    e[1] = new Element(C.VSRC,0,2,-1,-1,0,1,1,21);

    e[2] = new Element(C.VSRC,0,3,-1,-1,0,1,2,21);

    e[3] = new Element(C.VSRC,0,4,-1,-1,0,1,3,21);

    e[4] = new Element(C.VSRC,0,5,-1,-1,0,1,4,21);

    e[5] = new Element(C.VSRC,0,6,-1,-1,0,1,5,21);

    e[6] = new Element(C.VSRC,0,7,-1,-1,0,1,6,21);

    e[7] = new Element(C.VSRC,0,8,-1,-1,0,1,7,21);

    e[8] = new Element(C.G,1,9,-1,-1,0.00005,-1,-1,-1);

    e[9] = new Element(C.G,2,10,-1,-1,0.00005,-1,-1,-1);

    e[10] = new Element(C.G,3,11,-1,-1,0.00005,-1,-1,-1);

    e[11] = new Element(C.G,4,12,-1,-1,0.00005,-1,-1,-1);

    e[12] = new Element(C.G,5,13,-1,-1,0.00005,-1,-1,-1);

    e[13] = new Element(C.G,6,14,-1,-1,0.00005,-1,-1,-1);

    e[14] = new Element(C.G,7,15,-1,-1,0.00005,-1,-1,-1);

    e[15] = new Element(C.G,8,16,-1,-1,0.00005,-1,-1,-1);

    e[16] = new Element(C.G,0,9,-1,-1,0.00005,-1,-1,-1);

    e[17] = new Element(C.G,9,10,-1,-1,0.0001,-1,-1,-1);

    e[18] = new Element(C.G,10,11,-1,-1,0.0001,-1,-1,-1);

    e[19] = new Element(C.G,11,12,-1,-1,0.0001,-1,-1,-1);

    e[20] = new Element(C.G,12,13,-1,-1,0.0001,-1,-1,-1);

    e[21] = new Element(C.G,13,14,-1,-1,0.0001,-1,-1,-1);

    e[22] = new Element(C.G,14,15,-1,-1,0.0001,-1,-1,-1);

    e[23] = new Element(C.G,15,16,-1,-1,0.0001,-1,-1,-1);

   // e[24] = new Element(C.G,16,17,-1,-1,0.000000001,-1,-1,-1);

    //e[25] = new Element(C.G,17,18,-1,-1,0.0000000005,-1,-1,-1);

    //e[26] = new Element(C.G,18,0,-1,-1,0.001,-1,-1,-1);

    //e[27] = new Element(C.OpAmp,17,0,18,-1,-1,-1,-1,-1);

    */

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

   /* e[1] = new Element(C.D,2,1,-1,-1,0,0,1E-16,1/0.026);

    e[4] = new Element(C.G,3,2,-1,-1,1,-1,-1,-1);

    e[4] = new Element(C.CAC,3,2,-1,-1,1000,0,1,0.01);

    e[2] = new Element(C.G,3,0,-1,-1,1,-1,-1,-1);

    e[3] = new Element(C.OpAmp,2,0,3,-1,-1,-1,-1,-1);*/

 

 

  Solver S = new Solver();

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

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

   // 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,MCU,

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

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

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

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

   ////********logic////////////

 

   LogicElement[] le = new LogicElement[2];

  le[0] = new LogicElement(1,0,1,3);

  le[1] = new LogicElement(2,2,3,4);

  Logic logic45 = new Logic(5,le);

  boolean vals[] = {false, true,true,false,false};

  boolean[] res1 = logic45.SolveLogic(vals);

  boolean vals2[] = {true, true,true,false,true};

  boolean[] res2 = logic45.SolveLogic(vals2);

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

    System.out.println("res1="+res1[i]+"res2="+res2[i]);

  }

  // boolean nodeVals[] = {false, true, true, false, false};

  // boolean[] results = logic.SolveLogic(nodeVals);

  // System.out.println("LOGIC RESULTS:");

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

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

}

}

 

Logic:

package avrsimmx;

 

/**

 * <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 avrsimmx;

 

/**

 * <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;

  }

}

 

Parser:

package avrsimmx;

 

/**

 * <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];

  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());

      }

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

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

        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 = 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 avrsimmx;

 

/**

 * <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;

  byte[][] val; //= new byte[1][10010];

  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 the Compiled Linear Circuit

  //defined by the matrix equation Ax=z

  //for DC Analysis

 

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

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

    double[]z = new double[z0.length];

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

      z[i]=z0[i];

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

        A[i][j]=A0[i][j];

    }

    //Vector cointaining the results

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

    //Gaussian elimination algorithm

    //Reduce the matrix to upper triangular form

    for(int k =0; k<A.length-1; k++){

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

        for(int j = k+1 ; j<A.length; j++){

          A[i][j]=A[i][j]-(A[i][k]/A[k][k])*A[k][j];

          z[i]=z[i]-(A[i][k]/A[k][k])*z[k];

        }

      }

    }

    //Back substitute to get the final results

    x[A.length-1] = z[A.length-1]/A[A.length-1][A.length-1];

    for(int k =A.length-2; k>-1; k--){

    double temp = 0;

      for(int j = k+1; j<A.length; j++){

        temp = temp + A[k][j]*x[j];

      }

      x[k] = (z[k] - temp)/A[k][k];

    }

    //Return the vector containing the results

    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,

                          AT90S8515 MCU, String[] ID, int[] addr, int IDIndex,

                          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 byte[IDIndex][10001];

    else

      val = new byte[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);

    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));

        }

    }

 

    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)){

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

          tempPort = 5;

        }

        else{

          tempPort = 0;

        }

        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);

 

      }

      }

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

      PORTCInit = MCU.regFileIO[21];

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

      if(currentTime>=MCU.cycleNum){

        MCU.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***********************////////////

      if(IDIndex!=0){

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

          if(addr[i]<32){

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

          }

          else if(addr[i]<96){

            val[i][(int)currentTime]=MCU.regFileIO[addr[i]-32];

          }

          else{

            val[i][(int)currentTime]=MCU.SRAM[addr[i]-96];

          }

        }

      }

      /********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++){

          //System.out.println(nodeNumLogic[0]+"kkkkkkkkkkkkkkkkkkkkk");

           //System.out.println(newLogicVals.length+"newvalsloogiclength");

          //System.out.println(i);

         // System.out.println(newLogicVals[nodeNumLogic[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];

          }

        }

      //}

 

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

 

      //if(tempX!=x[17]){

      //System.out.println(x[17]);

      //cTime[cTimeIndex] = (int)currentTime;//MCU.cycleNum;

      //cTimeIndex++;

      //System.out.println("Current Time = "+currentTime +" cycleNum="+MCU.cycleNum);

      //}

    }

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

    //for(int i=0;i<100;i++){

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

    //}

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

    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 avrsimmx;

 

/**

 * <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 {

  AT90S8515 MCU= new AT90S8515();

  FileOutputStream f;

  //Return a string representing the binary equivalent of n

  public String decimalToBinary(byte n){

    String S = "";

    for(int i = 7; 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,byte[][] 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,byte[][] 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 avrsimmx;

 

/**

 * <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 {

  AT90S8515 MCU= new AT90S8515();

  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 file7777777777");

    }

 

  }

}