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.
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.
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.
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.
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.
Below is a listing of the code that can be compiled with any standard Java compiler.
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;
}
}
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;
}
}
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;
}
}
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]);
}
}
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;
}
}
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;
}
}
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));
}
}
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;
}
}
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");
}
}
}
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");
}
}
}