The purpose of this project was to extend the Mixed Signal AVR simulator written in Fall’02 so that any single-issue microprocessor could be included in the simulation environment rather than limiting the simulations to systems based around ATMEL AT90S8515 series microcontrollers. In order to achieve this goal, a general architectural description language (ADL) simulator was written and the user was provided with abtractions that allow the full specification of a microcontroller model and the corresponding memory hierarchy. Furthermore, the capabilities of the pre-existing simulator were extended to handle multiple microcontrollers at the same time. The final version of the mixed-signal MCU simulator was tested by implementing a 32-bit, single-issue MIPS microprocessor and L1-cache system. The correctness of this model was verified by comparing against a Verilog model of the same processor. In order to verify the operation of the ADL – Analog interface of the extended simulator, two instances of the MIPS processor were included in a sinewave-generator and run in parallel. Test results showed that the extended version of the simulator successfully handled two MIPS MCU’s running in parallel in a mixed-signal environment.
The final version of the simulator was written entirely in Java programming language. The code was organized roughly as depicted in the figure below, where each box represents a class and arrows denote the interaction of one class with another. On each arrow, outputs of one type of object that are passed to another object as inputs are shown (eg, the parser passes an array of logic elements to class Logic). For simplicity, only the major classes and the main inputs/outputs of those classes are shown, while a complete listing of the code can be found under the listing section.
-Program Organization-
The major difference between the current and the previous versions of the project is that the Hex File Reader has been replaced by the ADLSimulator class.
The ADLSimulator is the superclass of all MCU models and is intended to hide the unnecessary details of cycle-accurate simulation and analog – digital interfacing from the user. The ADLSimulator takes the MCU models, the states of the instruction memories at time t=0, and mask files as inputs. It generates instances of the models referenced in the netlist files and loads these models with the proper instructions. The loaded models are passed to the solver class.
Aside form this difference, the solver and the compiler classes were modified significantly to handle general CPU models rather than the hardcoded 8515 model, and further modifications to these files were made to simulate an arbitrary number of CPUs oncurrently. However, the basic working principles of the simulator, the analog-digital interfaces and the algorithms used for analog simulation have remained unchanged.
In order to test the operation of the simulator, two MIPS models were run in parallel in a sinewave – generator application. The first processor was used to generate the sinewave by performing memory mapped I/O. Memory address 0 was declared as a port in the netlist file, and this PORT was connected to the rest of the analog circuitry as shown below. In order to test correct parallel operation, the second CPU was loaded with instructions that toggle the memory location 0 between 0 and 1. for the second CPU, the least significant bit of memory location 0 was declared as a port and connected to ground through a 1K resistor (not shown). The netlist file that describes the se connections is shown below. The assembly instructions running on the processors is also listed. The corresponding MIPS model is included in the listing section.
R
1 9 20000 R
9 0 20000 R
2 10 20000 R
3 11 20000 R
4 12 20000 R
5 13 20000 R
6 14 20000 R
7 15 20000 R
8 16 20000 R
9 10 10000 R
10 11 10000 R
11 12 10000 R
12 13 10000 R
13 14 10000 R
14 15 10000 R
15 16 10000 PORT
1 0 0 cpu1 PORT
2 0 1 cpu1 PORT
3 0 2 cpu1 PORT
4 0 3 cpu1 PORT
5 0 4 cpu1 PORT
6 0 5 cpu1 PORT
7 0 6 cpu1 PORT
8 0 7 cpu1 PORT
19 0 0 cpu2 R
0 19 1000 OPAMP
17 0 18 R
17 18 2000000 R
18 0 1000 R
16 17 1000000 AND
1 2 20 OR 3 20 21 DUMPLOGIC
logicOUT 21 ENDDUMP DUMP
cpu1 portc 0 R0 0 R1 1 R2 2 R3 3 R4 5 R5 5 R6 6 R7 7 R8 8 R9 9 ENDDUMP DUMP
cpu2 reg2 0 ENDDUMP DUMPANALOG
opAmpOut1 18 bit0 19 dacOut 16 zeroOut 9 opAmpNegTerminal 17 ENDDUMP end
The netlist file describing the hardware in the schematics is provided at the right.
The first lines describe an R-2R ladder DAC, followed by the connections to the first
cpu and the logic gates. This is followed by the port declaration for the second cpu.
The dump statements at the end specify the nodes whose values are to be stored into
excel and vcd files for viewing after the simulation. These nodes are also named in the body of
the dump statements to facilitate the viewing process. A more detailed explanation
of the changes to the netlist file format can be found under the netlist files section.
The MIPS assembly instructions running on the two processors are listed below. The code was assembled using the ECE 475 MIPS cross compiler.
Sinewave Generator:
#Repeatedly load the next value of the sine function into memory address 0.
Label: li $1,0x80
sw $1, 0($0)
li $1, 0xb1
sw $1, 0($0)
li $1,0xda
sw $1, 0($0)
li $1,0xf6
sw $1, 0($0)
li $1, 0xff
sw $1, 0($0)
li $1, 0xf6
sw $1, 0($0)
li $1, 0xda
sw $1, 0($0)
li $1, 0xb1
sw $1, 0($0)
li $1, 0x80
sw $1, 0($0)
li $1, 0x4f
sw $1, 0($0)
li $1, 0x26
sw $1, 0($0)
li $1, 0x0a
sw $1, 0($0)
li $1, 0x00
sw $1, 0($0)
li $1, 0x0a
sw $1, 0($0)
li $1, 0x26
sw $1, 0($0)
li $1, 0x4f
sw $1, 0($0)
j Label
Toggle Mem[0]:
#Toggle memory location 0 between 0 and 1
Label: li $2, 0
sw $2, 0($0)
li $2, 1
sw $2, 0($0)
j Label
The results of the simulation are shown below. The plots are taken directly form the excel file generated by the simulator, where the node names agree with the definitions in the dump statements. The plot on the left shows the output of the DAC and the output of the Op Amp vs. time. The plot on the right shows the voltage on the second cpu’s port as a function of time. The microcontrollers spend the initial 40 cycles warming up the L1 cache. After this point, the sine values are stable. The second cpu is also affected by the cache miss in the same way.
Figure 1
Figure 2
The results of the digital simulation are shown below. The bottom 3 rows show the output of the logic gates, the values of the emory location for CPU1 and CPU2, respectively.
Figure 3
As expected CPU1 sets MEM[0] to the sine values while the second CPU toggles its MEM[0].
The only update to the netlist files in this version of the simulator is the syntax of the PORT declarations. PORT declarations must now have the name of the corresponding CPU as their first argument since there can be more than one processor running simulataneously. Hence, a typical PORT declaration would look like:
PORT cpu_name node_number IO_address bit_number.
Other than this difference, the format of the Netlist file remained unchanged.
In order for the ADL simulator to correctly distinguish between instructions, a mask file that describes the opcodes of the instructions is necessary. As different ISA’s encode instructions differently, the mask file consists of a list of entries that gives the name of the instruction, a bitmask, a key and an instruction format. These fields are separated by semicolons:
Instruction_name : bit_mask : key : instruction_format
At runtime, the ADL simulator performs a logical AND between the current instruction and a the bit mask. If the result is equal to the key, the getArgs() function is called with the given instruction format and the corresponding instruction is executed with the resulting arguments. Hence, the bitmask/key pair can be used to distinguish between instructions in any ISA.
In order to specify a processor model, the user must write a java file that extends ADLSimulator. The key features of these models are listed below while an example is provided in the listing section:
All instructions are represented by methods that have the following signature:
public void instruction_name( Integer[] args){}
The args[] array is an array of arguments that will be extracted from the instruction based on the corresponding instruction format. Within the body of the method, the uiser is free to use any features of the simulator as well as any general java constructs.
In order for the arguments of the instructions to be extracted properly, the user must provide the following function:
public Integer[] getArgs(String format, long Instruction){}
Once the current instruction is compared against the entries in the mask file, the corresponding format string will be passed to getArgs with the instruction.
GetArgs must extract the arguments from the instruction and return them in an array.
PC is a reserved key word and represents the program counter. The user can specify how the instruction changes the PC by peforming operations on this
Identifier (eg. PC++; will increment the PC for the next iteration of the simulation).
The latency of every instruction is 1 cycle by default. However, the user can change this by using the LATENCY keyword. For instance, using
“LATENCY = 32;” within the body of an instruction will cause the instruction to have a 32 cycle latency. Instructions that access the memory hierarcy
will have a variable latency based on the cache hits and misses and the latencies will be calculated by simulator at runtime.
The keyword “R” is used to represent the register file. The register file is an array of integers whose length must be specified by the used.
The data memory can be specified either as a single main memory or as a memory hierarchy. If there are no caches, then the keyword DMEM must be used to access data memory. DMEM is an array of integers whose length must be specified by the used.
If a memory hierarchy with caches is present, the DMEMH keyword will represent the hierarchy. DMEMH.putWord(int address, long data) can be used for stores, and DMEMH.getWord(int address) can be used for loads.
The constructor for instantiating a new cache has the following signature. The user can call this constructor to instantiate a cache in the constructor for the MCU model.
public Cache(int blockSize, int Associativity, int Replacement, int NumLines, Mem Parent,int Latency){}
The first 4 arguments are regular cache parameters. Parent is either another cache or MainMem that is immediatelyabove this cache in the hierarchy.
Latency is the access time of the cache.
The constructor for the main memory is shown below
public MainMem(int accessTime){}
The main memory must be the topmost node of every memory hierarchy for correct operation.
Aside from these features, the following methods are provided as abstractions to the user:
public void beforeInst(){} : will be called before every instruction
public void afterInst(){} : will be called after every instruction
public void always(){} : will be called every cycle
public void init(){} : will be called before the simulation starts, after the CPU model is loaded with instructions
public void finish(){} : will be called after the simulation ends
Given enough time, the simulator could be optimized by performing sparse matrix techniques in analog simulation. This would significantly reduce the simulation time of mixed signal systems with a high number of analog components.
Below is a listing of the code that can be compiled with any standard Java compiler.
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class ADLSimulator {
//name of the processor
public String name;
//Number of cycles passed so far
public long cycleNum;
//Pipeline structure
public String PIPELINE;
//DMEM size
public int dmemSize;
//RF size
public int regfileSize;
//Register File
public int[] R;
//PC
public int PC;
//Latency of the instruction
public int LATENCY;
//Data memory
public long DMEM[];
//Fetcher
public fetcher f;
//Memory Hierarchy
public Mem DMEMH;
//Constructor
public ADLSimulator(String instFile, String maskFile,int dmemSize,int regfileSize,String PIPELINE){
DMEMH = new Mem();
cycleNum = 0;
PC = 0;
LATENCY = 1;
f = new fetcher(instFile, maskFile);
DMEM = new long[dmemSize];
// DMEM = Mem.vals;
R = new int[regfileSize];
}
//Constructor
public ADLSimulator(){
}
//Template for getArgs
public Integer[] getArgs(String format, long instruction){
return null;
}
//Step the CPU
public void run() {
LATENCY = 1;
beforeInst();
f.run(PC,this);
cycleNum = cycleNum + LATENCY;
afterInst();
}
//Initialization
public void init(){}
//Last call
public void finish(){}
//Called once before every instruction
public void beforeInst(){}
//Called once after every instruction
public void afterInst(){}
public boolean getBit(byte b, int bitNum) {
byte temp = 1;
return ( (b & (temp << bitNum)) != 0);
}
public boolean getBit(int i, int bitNum) {
int temp = 1;
return ( (i & (temp << bitNum)) != 0);
}
public boolean getBit(long i, int bitNum) {
int temp = 1;
return ( (i & (temp << bitNum)) != 0);
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
//Memory Hierarchy simulation class
public class Cache extends Mem{
//Statistics
public long numMisses;
public long numHits;
//Cache parameters
int byteOffsetLength;
int associativity;
int replacement;
int numLines;
int numLinesLog2;
//Upper level of Mem hierarchy
Mem parent;
//Tags and data
long[][] tags;
int fifo[][];
public int log2(int powerOf2){
int i = 0;
for(int j=1; j != 0; j = j <<1){
if((powerOf2 & j) != 0)
break;
i++;
}
return i;
}
public Cache(int blockSize, int Associativity, int Replacement, int NumLines, Mem Parent,int Latency){
numMisses = 0;
numHits = 0;
tags = new long[NumLines][Associativity];
fifo = new int[NumLines][Associativity];
for(int i = 0; i < tags.length; i++){
for(int j = 0; j < tags[0].length; j++){
tags[i][j] = -1;
fifo[i][j] = j;
}
}
byteOffsetLength = log2(blockSize);
associativity = Associativity;
replacement = Replacement;
numLines = NumLines;
parent = Parent;
latency = Latency;
numLinesLog2 = log2(NumLines);
}
public long getWord(int address){
totalLatency = totalLatency + latency;
long result = vals[address];
int index = (int)((address >>> byteOffsetLength) & (numLines - 1));
long tag = address >>> (byteOffsetLength + numLinesLog2);
for(int i = 0; i < tags[0].length; i++){
if(tags[index][i] == tag){
numHits++;
return vals[address];
}
}
numMisses++;
tags[index][getSet(index)] = tag;
long temp = parent.getWord(address);
return result;
}
public void putWord(int address, long data){
vals[address] = data;
totalLatency = totalLatency + latency;
int index = (int)((address >>> byteOffsetLength) & (numLines - 1));
long tag = address >>> (byteOffsetLength + numLinesLog2);
for(int i = 0; i < tags[0].length; i++){
if(tags[index][i] == tag){
numHits++;
return;
}
}
numMisses++;
tags[index][getSet(index)] = tag;
parent.putWord(address,data);
}
public int getSet(int index){
if(replacement == RANDOM){
return (int)Math.random()*associativity;
}
else if(replacement == FIFO){
fifo[index][fifo[index].length-1] = fifo[index][0];
for(int i = 0; i < fifo[index].length - 1; i++){
fifo[index][i] = fifo[index][i+1];
}
return fifo[index][0];
}
else return 0;
}
public long getNumHits(){
return numHits;
}
public long getNumMisses(){
return numMisses;
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
public class Compiler {
final int G = 0;
final int VSRC = 1;
final int CSRC = 2;
final int CCVS = 3;
final int CCCS = 4;
final int VCVS = 5;
final int VCCS = 6;
final int OpAmp = 7;
final int GI = 8;
final int D = 9;
final int CAC = 10;
final int CDC = 11;
final int VAC = 12;
double x[];
double z[];
//Compile the circuit & formulate the matrixsys
public double[][] Compile(Element[] e, int noOfNodes) {
Element[] element = new Element[e.length];
for(int i = 0; i< element.length; i++){
//System.out.println(e[i].TYPE+" "+e[i].nj+" "+e[i].nk+" "+e[i].np+" "+e[i].nq+" "+e[i].p+" "+e[i].pnl0
// +" "+e[i].pnl1+" "+e[i].pnl2);
element[i] = new Element(e[i].TYPE,e[i].nj,e[i].nk,e[i].np,e[i].nq,e[i].p,e[i].pnl0,e[i].pnl1,e[i].pnl2);
element[i].MCU = e[i].MCU;
}
// System.out.println("*******************************************************************");
//Find the number of additional current variables needed
// & generate additional current variables for dependent sources
int m = 0;
int iTemp = 1;
for(int i = 0; i < element.length ; i++){
if((element[i].TYPE == VSRC) |
(element[i].TYPE == VAC) |
(element[i].TYPE == VCVS) |
(element[i].TYPE == GI) |
(element[i].TYPE == CCCS) |
(element[i].TYPE == OpAmp)){
m++;
element[i].iVar0 = iTemp;
iTemp++;
}
if(element[i].TYPE == CCVS){
m = m+2;
element[i].iVar0 = iTemp;
element[i].iVar1 = iTemp + 1;
iTemp = iTemp + 2;
}
}
//Initialize the matrix & vectors
double A[][] = new double[noOfNodes+m][noOfNodes+m];
x = new double[noOfNodes+m];
z = new double[noOfNodes+m];
//Process the element list
for(int i = 0; i < element.length ; i++){
element[i].nj--;
element[i].nk--;
element[i].np--;
element[i].nq--;
switch(element[i].TYPE){
//Conductance
case G:
if(element[i].nj>-1)
A[element[i].nj][element[i].nj] = A[element[i].nj][element[i].nj] + element[i].p;
if(element[i].nk>-1)
A[element[i].nk][element[i].nk] = A[element[i].nk][element[i].nk] + element[i].p;
if((element[i].nj>-1)&&(element[i].nk>-1)){
A[element[i].nj][element[i].nk] = A[element[i].nj][element[i].nk] - element[i].p;
A[element[i].nk][element[i].nj] = A[element[i].nk][element[i].nj] - element[i].p;
}
break;
//Current Source
case CSRC:
if(element[i].nj>-1)
z[element[i].nj] = z[element[i].nj] + element[i].p;
if(element[i].nk>-1)
z[element[i].nk] = z[element[i].nk] - element[i].p;
break;
//Voltage Source
case VSRC:
if(element[i].nk>-1)
A[element[i].nk][element[i].iVar0 + noOfNodes - 1]++;
if(element[i].nj>-1)
A[element[i].nj][element[i].iVar0 + noOfNodes - 1]--;
if(element[i].nk>-1)
A[element[i].iVar0 + noOfNodes -1][element[i].nk]++;
if(element[i].nj>-1)
A[element[i].iVar0 + noOfNodes -1][element[i].nj]--;
z[element[i].iVar0 + noOfNodes -1] = element[i].p;
break;
//Current Controlled Voltage Source
case CCVS:
if(element[i].nk>-1)
A[element[i].nk][element[i].iVar0 +noOfNodes -1]++;
if(element[i].nj>-1)
A[element[i].nj][element[i].iVar0+noOfNodes -1]--;
if(element[i].nk>-1)
A[element[i].iVar1 +noOfNodes-1][element[i].nk]++;
if(element[i].nj>-1)
A[element[i].iVar1 +noOfNodes-1][element[i].nj]--;
A[element[i].iVar1 +noOfNodes-1][element[i].iVar1 +noOfNodes-1] =
A[element[i].iVar1 +noOfNodes-1][element[i].iVar1 +noOfNodes-1] + element[i].p;
break;
//Voltage Controlled Voltage Source
case VCVS:
if(element[i].nk>-1)
A[element[i].nk][element[i].iVar0 +noOfNodes -1]++;
if(element[i].nj>-1)
A[element[i].nj][element[i].iVar0+noOfNodes -1]--;
if(element[i].nk>-1)
A[element[i].iVar0 +noOfNodes-1][element[i].nk]++;
if(element[i].nj>-1)
A[element[i].iVar0 +noOfNodes-1][element[i].nj]--;
if(element[i].np>-1)
A[element[i].iVar0 +noOfNodes-1][element[i].np]= A[element[i].iVar0 +noOfNodes-1][element[i].np]-element[i].p;
if(element[i].nq>-1)
A[element[i].iVar0 +noOfNodes-1][element[i].nq]= A[element[i].iVar0 +noOfNodes-1][element[i].nq]+element[i].p;
break;
//Current Controlled Current Source
case CCCS:
if(element[i].nk>-1)
A[element[i].nk][element[i].iVar0+noOfNodes -1] = A[element[i].nk][element[i].iVar0+noOfNodes -1] +element[i].p;
if(element[i].nj>-1)
A[element[i].nj][element[i].iVar0+noOfNodes -1] = A[element[i].nj][element[i].iVar0+noOfNodes -1] -element[i].p;
break;
//Voltage Controlled Current Source
case VCCS:
if((element[i].nk>-1)&&(element[i].np>-1))
A[element[i].nk][element[i].np]=A[element[i].nk][element[i].np]+element[i].p;
if((element[i].nk>-1)&&(element[i].nq>-1))
A[element[i].nk][element[i].nq]=A[element[i].nk][element[i].nq]-element[i].p;
if((element[i].nj>-1)&&(element[i].np>-1))
A[element[i].nj][element[i].np]=A[element[i].nj][element[i].np]-element[i].p;
if((element[i].nj>-1)&&(element[i].nq>-1))
A[element[i].nj][element[i].nq]=A[element[i].nj][element[i].nq]+element[i].p;
break;
//Ideal Op Amp
case OpAmp:
if(element[i].np>-1)
A[element[i].np][element[i].iVar0+noOfNodes-1]++;
if(element[i].nk>-1)
A[element[i].iVar0+noOfNodes-1][element[i].nk]++;
if(element[i].nj>-1)
A[element[i].iVar0+noOfNodes-1][element[i].nj]--;
break;
//Conductance with current as an output variable
case GI:
if(element[i].nk>-1)
A[element[i].nk][element[i].iVar0+noOfNodes-1]++;
if(element[i].nj>-1)
A[element[i].nj][element[i].iVar0+noOfNodes-1]--;
if(element[i].nk>-1)
A[element[i].iVar0+noOfNodes-1][element[i].nk]=A[element[i].iVar0+noOfNodes-1][element[i].nk]+element[i].p;
if(element[i].nj>-1)
A[element[i].iVar0+noOfNodes-1][element[i].nj]=A[element[i].iVar0+noOfNodes-1][element[i].nj]-element[i].p;
A[element[i].iVar0+noOfNodes-1][element[i].iVar0+noOfNodes-1]--;
break;
//Diode
case D:
if(element[i].nj>-1){
A[element[i].nj][element[i].nj] = A[element[i].nj][element[i].nj] + element[i].p;
z[element[i].nj]=z[element[i].nj]+element[i].pnl0;
}
if(element[i].nk>-1){
A[element[i].nk][element[i].nk] = A[element[i].nk][element[i].nk] + element[i].p;
z[element[i].nk]=z[element[i].nk]-element[i].pnl0;
}
if((element[i].nj>-1)&&(element[i].nk>-1)){
A[element[i].nj][element[i].nk] = A[element[i].nj][element[i].nk] - element[i].p;
A[element[i].nk][element[i].nj] = A[element[i].nk][element[i].nj] - element[i].p;
}
break;
//Capacitor
case CAC:
if(element[i].nj>-1){
A[element[i].nj][element[i].nj] = A[element[i].nj][element[i].nj] + element[i].p;
z[element[i].nj]=z[element[i].nj]-element[i].pnl0;
}
if(element[i].nk>-1){
A[element[i].nk][element[i].nk] = A[element[i].nk][element[i].nk] + element[i].p;
z[element[i].nk]=z[element[i].nk]+element[i].pnl0;
}
if((element[i].nj>-1)&&(element[i].nk>-1)){
A[element[i].nj][element[i].nk] = A[element[i].nj][element[i].nk] - element[i].p;
A[element[i].nk][element[i].nj] = A[element[i].nk][element[i].nj] - element[i].p;
}
break;
//VAC
case VAC:
if(element[i].nk>-1)
A[element[i].nk][element[i].iVar0 + noOfNodes - 1]++;
if(element[i].nj>-1)
A[element[i].nj][element[i].iVar0 + noOfNodes - 1]--;
if(element[i].nk>-1)
A[element[i].iVar0 + noOfNodes -1][element[i].nk]++;
if(element[i].nj>-1)
A[element[i].iVar0 + noOfNodes -1][element[i].nj]--;
z[element[i].iVar0 + noOfNodes -1] = element[i].p;
break;
}
}
return A;
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
public class Element {
//Corresponding MCU for PORTS
String MCU ;
//Type of the circuit element
public int TYPE = 0;
//Nodes connected to the element
public int nj, nk, np, nq;
//Parameter related to the element
public double p, pnl0, pnl1,pnl2;
//Additional current variables
public int iVar0, iVar1;
//Initizalize an element from given nodes and a parameter
public Element(int type, int Nj, int Nk, int Np, int Nq, double p0, double pn0,double pn1, double pn2) {
TYPE = type;
nj = Nj;
nk = Nk;
np = Np;
nq = Nq;
p = p0;
pnl0 = pn0;
pnl1 = pn1;
pnl2 = pn2;
}
}
package adlsim;
import java.util.*;
import java.io.*;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class fetcher {
long[] Mem;
long[] masks;
// Integer[] array;
// Integer single;
// Object[] args = {single,array};
Hashtable functions;
Hashtable formats;
FileReader f;
BufferedReader br;
public fetcher(String instFile, String maskFile) {
functions = new Hashtable();
formats = new Hashtable();
try{
// Create a new file reader
// connected to maskFile
FileReader f = new FileReader(maskFile);
BufferedReader br = new BufferedReader(f);
// Create a new file reader
// connected to instFile
FileReader fi = new FileReader(instFile);
BufferedReader bri = new BufferedReader(fi);
//Vector for decoding the instruction file
Vector instrs = new Vector();
//Load the instructions
String str = bri.readLine();
String[] strArray = str.split(" ");
String str0 = strArray[1].substring(0,10);
String str1 = "0x"+strArray[1].substring(10,18);
//System.out.println(str0+ " " + str1);
while(str!=null){
strArray = str.split(" ");
str0 = strArray[1].substring(0,10);
str1 = "0x"+strArray[1].substring(10,18);
instrs.add(str0);
instrs.add(str1);
str = bri.readLine();
}
Mem = new long[instrs.size()];
for(int i = 0; i<Mem.length; i++){
Mem[i] = Long.decode((String)instrs.get(i)).longValue();
}
//Vectors for decoding the mask file
Vector fun = new Vector();
Vector msk = new Vector();
Vector key = new Vector();
Vector format = new Vector();
//Walk through the msk file and set parameters
String s = br.readLine();
while(s != null){
String line[] = s.split(":");
fun.add(line[0]);
msk.add(line[1]);
key.add(line[2]);
format.add(line[3]);
s = br.readLine();
}
//Insert the masks
masks = new long[msk.size()];
for(int i = 0 ; i < masks.length; i++){
masks[i] = Long.decode((String)msk.get(i)).longValue();
}
//Insert the functions
for(int i = 0; i < key.size(); i++){
functions.put(Long.decode((String)key.get(i)),fun.get(i));
}
//Bind the formats
for(int i = 0; i < format.size(); i++){
formats.put(Long.decode((String)key.get(i)),format.get(i));
}
}
catch(Exception exc){System.out.println("Error in mask file or hex file.");}
}
public void runAlways(){
}
public void runInit(){
}
public void runFini(){
}
//Run the instruction at the given index with the given CPU state
public void run(int index, ADLSimulator mcu){
Integer[] temp = new Integer[1];
Integer[] args;
Class[] types = {temp.getClass()};
String funName = null;
String formatName = null;
long instruction = Mem[index];
//Get the correct format name
for(int i = 0; i < masks.length; i++){
formatName = (String)formats.get((new Long((int)masks[i] & instruction)));
if(formatName != null)
break;
}
//Get the arguments
args = mcu.getArgs(formatName,instruction);
//Get the correct function name
for(int i = 0; i < masks.length; i++){
funName = (String)functions.get((new Long((int)masks[i] & instruction)));
if(funName != null)
break;
}
try{
Object[] wrapper = {args};
mcu.getClass().getMethod(funName,types).invoke(mcu,wrapper);
}
catch(Exception e){
System.out.println("Instruction description for \"" +funName+ "\" not found in MCU.java");
}
}
}
package adlsim;
/**
* <p>Title: AVRSim</p>
* <p>Description: Mixed Signal AVR Simulator</p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: Cornell University</p>
* @author unascribed
* @version 1.0
*/
import java.io.*;
public class HexReader {
FileReader f; // declare a file reader object
private int recordLength = 0;
private String recordLengthS;
private int address = 0;
private String addressS;
private char[] buffer = new char[100];
private int index;
private int dataIndex;
public void loadMEM(String S, short[] Mem){
try{
// Create a new file reader
// connected to S
f = new FileReader(S);
BufferedReader br = new BufferedReader(f);
index = 0;
dataIndex = 9;
char[] temp0 = (br.readLine()).toCharArray();
int countMod4 = 0;
while(index<9){
buffer[index] = temp0[index];
index++;
}
while(index<temp0.length-2){
if(countMod4 < 2)
buffer[index+2] = temp0[index];
else
buffer[index-2] = temp0[index];
index++;
countMod4 = (countMod4 + 1)%4;
}
while((buffer[7] != '0') | (buffer[8] != '1')){
//System.out.println("temp0:"+String.valueOf(temp0));
//System.out.println("temp0.length=" +temp0.length);
/// System.out.println("Buffer:"+String.valueOf(buffer));
index = 0;
dataIndex = 9;
recordLengthS = "0x" +String.copyValueOf(buffer,1,2);
addressS = "0x"+String.copyValueOf(buffer,3,4);
recordLength = 2*Integer.decode(recordLengthS).intValue();
address = Integer.decode(addressS).intValue()/2;
while(recordLength > 0){
Mem[address] = (short)(Integer.decode("0x"+String.copyValueOf(buffer,dataIndex,4)).intValue());
//System.out.println("MEM["+address+"]="+String.copyValueOf(buffer,dataIndex,4));
dataIndex = dataIndex +4;
address++;
recordLength = recordLength - 4;
}
char[] temp = (br.readLine()).toCharArray();
index = 0;
countMod4 = 0;
while(index<9){
buffer[index] = temp[index];
index++;
}
while(index<temp.length-2){
if(countMod4 < 2)
buffer[index+2] = temp[index];
else
buffer[index-2] = temp[index];
index++;
countMod4 = (countMod4 + 1)%4;
}
}
}
catch (Exception e){
System.err.println ("Error reading file");
}
}
public static void main(String[] args){
String h = "hello";
char[] hello = h.toCharArray();
for(int i = 0; i < hello.length; i++){
System.out.println((int)hello[i]);
}
ADLSimulator MCU = new MCU("INST.txt","MASK.txt","cpu1");
ADLSimulator MCU2 = new MCU("INST2.txt", "MASK.txt","cpu2");
ADLSimulator MCUs[] = {MCU,MCU2};
Parser p = new Parser();
Element[] e = p.Parse("itestsinewave.net");
Compiler C = new Compiler();
Solver S = new Solver();
double[][]A = C.Compile(e,19);
// System.out.println("TIME IS:" + System.currentTimeMillis());
Logic logic = new Logic(22,p.el);
double[] x = S.SolveAC(A,C.z,1,1,10000,e,MCUs,
p.ID,p.dataAddr,p.IDIndex,p.mcuName,
p.IDAnalog,p.nodeNum,p.IDIndexAnalog,
p.IDLogic,p.nodeNumLogic,p.IDIndexLogic,logic);
// System.out.println("TIME IS:" + System.currentTimeMillis());
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
public class Logic {
final int AND = 1;
final int OR = 2;
final int NOT = 3;
final int DFF = 4;
public boolean oldNodeVals[];
public boolean[] externalInputs;
public LogicElement[] le;
public Logic(int noOfNodes, LogicElement[] Le){
oldNodeVals = new boolean[noOfNodes];
le = new LogicElement[Le.length];
for(int i =0;i<Le.length; i++){
le[i] = Le[i];
}
externalInputs = new boolean[noOfNodes];
for(int i=0; i<externalInputs.length; i++){
externalInputs[i]=true;
}
for(int i=0; i<le.length; i++){
//System.out.println("in1:"+le[i].in1);
//System.out.println("in2:"+le[i].in2);
// System.out.println("out:"+le[i].out);
for(int j=0;j<le.length; j++){
if(le[i].in1==le[j].out)
externalInputs[le[i].in1]=false;
if(le[i].in2==le[j].out)
externalInputs[le[i].in2]=false;
externalInputs[le[j].out]=false;
}
}
}
public boolean[] SolveLogic(boolean[] nodeVals){
boolean updatedNodes[] = new boolean[nodeVals.length];
for(int i = 0; i<nodeVals.length; i++){
updatedNodes[i] = (oldNodeVals[i]!=nodeVals[i]);
}
boolean Done = false;
while(!Done){
for(int upIndex = 0 ; upIndex < updatedNodes.length; upIndex++){
if(updatedNodes[upIndex]){
updatedNodes[upIndex] = false;
for(int leIndex = 0; leIndex<le.length; leIndex++){
if((le[leIndex].in1 == upIndex)|(le[leIndex].in2 == upIndex)){
if(le[leIndex].TYPE == AND){
updatedNodes[le[leIndex].out] =
((nodeVals[le[leIndex].in1]&nodeVals[le[leIndex].in2])== nodeVals[le[leIndex].out]);
nodeVals[le[leIndex].out] = nodeVals[le[leIndex].in1]&nodeVals[le[leIndex].in2];
}
else if(le[leIndex].TYPE == OR){
updatedNodes[le[leIndex].out] =
(nodeVals[le[leIndex].in1]|nodeVals[le[leIndex].in2]==nodeVals[le[leIndex].out]);
nodeVals[le[leIndex].out] = nodeVals[le[leIndex].in1]|nodeVals[le[leIndex].in2];
}
else if(le[leIndex].TYPE == DFF){
updatedNodes[le[leIndex].out] =
(nodeVals[le[leIndex].out]==(nodeVals[le[leIndex].in1]&(le[leIndex].in2==upIndex)&
nodeVals[le[leIndex].in2]));
nodeVals[le[leIndex].out] =
nodeVals[le[leIndex].in1]&(le[leIndex].in2 == upIndex)&nodeVals[le[leIndex].in2];
}
}
}
}
}
Done = true;
for(int i=0; i < updatedNodes.length; i++){
if(updatedNodes[i])
Done = false;
}
}
for(int i = 0; i<nodeVals.length; i++){
oldNodeVals[i]=nodeVals[i];
}
return nodeVals;
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
public class LogicElement {
public int TYPE = 0;
public int in1 = 0;
public int in2 = 0;
public int out = 0;
public LogicElement(int Type, int In1, int In2, int Out) {
TYPE= Type;
in1 = In1;
in2 = In2;
out = Out;
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class MainMem extends Mem{
public MainMem(int accessTime) {
latency = accessTime;
}
public long getWord(int address){
//System.out.println("L1 Miss");
totalLatency = totalLatency + latency;
return vals[address];
}
public void putWord(int address, long data){
vals[address] = data;
totalLatency = totalLatency + latency;
}
}
package adlsim;
import java.util.*;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
public class MCU extends ADLSimulator {
int HI, LO;
int target;
boolean delaySlot, branch;
//This constructor must be present in the MCU file
public MCU(String instFile, String maskFile, String cpuName) {
super(instFile, maskFile, 100, 32, "IF|RD|EX|MEM|WB");
name = cpuName;
//Initialize memory hierarchy
MainMem m = new MainMem(40);
Cache L1 = new Cache(32, 2, Mem.RANDOM, 512, m, 1);
DMEMH = L1;
//This line must be present when modeling caches
DMEM = DMEMH.vals;
}
//Extract the arguments from the instruction word based on the instruction format
public Integer[] getArgs(String format, long instruction) {
Integer[] args = new Integer[3];
//I-type
if (format.equals("I")) {
args[0] = new Integer( (int) ( (instruction >>> 21) & 0x0000001f));
args[1] = new Integer( (int) ( (instruction >>> 16) & 0x0000001f));
args[2] = new Integer( (int) (instruction & 0x0000ffff));
if ( (args[2].intValue() & 0x00008000) != 0) {
args[2] = new Integer(args[2].intValue() | 0xffff0000);
}
}
//J-type
else if (format.equals("J")) {
args = new Integer[1];
args[0] = new Integer( (int) (instruction & 0x03ffffff));
}
//R-type
else if (format.equals("R")) {
args = new Integer[4];
args[0] = new Integer( (int) ( (instruction >>> 21) & 0x0000001f));
args[1] = new Integer( (int) ( (instruction >>> 16) & 0x0000001f));
args[2] = new Integer( (int) ( (instruction >>> 11) & 0x0000001f));
args[3] = new Integer( (int) ( (instruction >>> 6) & 0x0000001f));
}
return args;
}
/******************** INSTRUCTIONS ************************************/
//Add
public void add(Integer[] args) {
R[args[2].intValue()] = R[args[0].intValue()] + R[args[1].intValue()];
PC++;
}
//Addu
public void addu(Integer[] args) {
R[args[2].intValue()] = R[args[0].intValue()] + R[args[1].intValue()];
PC++;
}
//And
public void and(Integer[] args) {
R[args[2].intValue()] = R[args[0].intValue()] & R[args[1].intValue()];
PC++;
}
//Div
public void div(Integer[] args) {
LO = R[args[0].intValue()] / R[args[1].intValue()];
HI = R[args[0].intValue()] % R[args[1].intValue()];
PC++;
LATENCY = 32;
}
//Divu
public void divu(Integer[] args) {
LO = R[args[0].intValue()] / R[args[1].intValue()];
HI = R[args[0].intValue()] % R[args[1].intValue()];
PC++;
LATENCY = 32;
}
//Or
public void or(Integer[] args) {
R[args[2].intValue()] = R[args[0].intValue()] | R[args[1].intValue()];
PC++;
}
//Nor
public void nor(Integer[] args) {
R[args[2].intValue()] = ~ (R[args[0].intValue()] | R[args[1].intValue()]);
PC++;
}
//Sll
public void sll(Integer[] args) {
R[args[2].intValue()] = R[args[1].intValue()] << R[args[3].intValue()];
PC++;
}
//Sllv
public void sllv(Integer[] args) {
R[args[2].intValue()] = R[args[1].intValue()] << R[args[0].intValue()];
PC++;
}
//Addiu
public void addiu(Integer[] args) {
R[args[1].intValue()] = R[args[0].intValue()] + args[2].intValue();
PC++;
}
//Lw
public void lw(Integer[] args) {
DMEMH.putWord(R[args[0].intValue()] + args[2].intValue(),
R[args[1].intValue()]);
PC++;
}
//Sw
public void sw(Integer[] args) {
DMEMH.totalLatency = 0;
DMEMH.putWord(args[0].intValue() + args[2].intValue(), R[args[1].intValue()]);
LATENCY = DMEMH.totalLatency;
PC++;
}
//J
public void j(Integer[] args) {
target = args[0].intValue();
branch = true;
PC++;
}
//Beq
public void beq(Integer[] args) {
target = PC + 1 + args[2].intValue();
if (R[args[0].intValue()] == R[args[1].intValue()]) {
branch = true;
}
PC++;
}
//Bne
public void bne(Integer[] args) {
target = PC + 1 + args[2].intValue();
if (R[args[0].intValue()] != R[args[1].intValue()]) {
branch = true;
}
PC++;
}
//Bgez
public void bgez(Integer[] args) {
target = PC + 1 + args[2].intValue();
if (R[args[0].intValue()] >= 0) {
branch = true;
}
PC++;
}
//Bgtz
public void bgtz(Integer[] args) {
target = PC + 1 + args[2].intValue();
if (R[args[0].intValue()] > 0) {
branch = true;
}
PC++;
}
//Blez
public void blez(Integer[] args) {
target = PC + 1 + args[2].intValue();
if (R[args[0].intValue()] <= 0) {
branch = true;
}
PC++;
}
//Bltz
public void bltz(Integer[] args) {
target = PC + 1 + args[2].intValue();
if (R[args[0].intValue()] < 0) {
branch = true;
}
PC++;
}
//Ori
public void ori(Integer[] args) {
R[args[1].intValue()] = R[args[0].intValue()] | R[args[2].intValue()];
PC++;
}
//Addi
public void addi(Integer[] args) {
R[args[1].intValue()] = R[args[0].intValue()] + R[args[2].intValue()];
PC++;
}
//Andi
public void andi(Integer[] args) {
R[args[1].intValue()] = R[args[0].intValue()] & R[args[2].intValue()];
PC++;
}
//Xori
public void xori(Integer[] args) {
R[args[1].intValue()] = R[args[0].intValue()] ^ R[args[2].intValue()];
PC++;
}
//Slti
public void slti(Integer[] args) {
R[args[1].intValue()] = (R[args[0].intValue()] < R[args[2].intValue()]) ? 1 :
0;
PC++;
}
//Sub
public void sub(Integer[] args) {
R[args[2].intValue()] = R[args[0].intValue()] - R[args[1].intValue()];
PC++;
}
//Xor
public void xor(Integer[] args) {
R[args[2].intValue()] = R[args[0].intValue()] ^ R[args[1].intValue()];
PC++;
}
//Mult
public void mult(Integer[] args) {
long product = R[args[0].intValue()] * R[args[1].intValue()];
HI = (int) (product >>> 32);
LO = (int) (product & 0x00000000ffffffff);
PC = PC + 32;
}
//Mflo
public void mflo(Integer[] args) {
R[args[2].intValue()] = LO;
PC++;
}
//Mfhi
public void mfhi(Integer[] args) {
R[args[2].intValue()] = HI;
PC++;
}
//Called last
public void finish() {
System.out.println("L1 hits: " + DMEMH.getNumHits());
System.out.println("L1 misses: " + DMEMH.getNumMisses());
}
public void afterInst() {
if (branch) {
branch = false;
delaySlot = true;
}
if (delaySlot) {
delaySlot = false;
PC = target;
}
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class Mem {
//Replacement policies
public static final int FIFO = 0;
public static final int LRU = 1;
public static final int RANDOM = 2;
public long vals[];
//Latency
int latency;
static int totalLatency;
public Mem() {
totalLatency = 0;
vals = new long[200000];
}
public long getWord(int addr){
return 0;
}
public void putWord(int addr, long data){
}
public long getNumHits(){
return 0;
}
public long getNumMisses(){
return 0;
}
}
package adlsim;
/**
* <p>Title: </p>inde
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
import java.io.*;
public class Parser {
public String hexFile= "";
public int index = 0;
public int indexLogic=0;
public Element[] element = new Element[1000];
public LogicElement[] elementLogic = new LogicElement[1000];
public LogicElement[] el;
public int[] dataAddr= new int[600];
public int[] nodeNum = new int[600];
public int[] nodeNumLogic = new int[600];
public String[] ID = new String[600];
public String[] IDAnalog = new String[600];
public String[] IDLogic = new String[600];
public String[] mcuName = new String[600];
int IDIndex = 0;
int IDIndexAnalog = 0;
int IDIndexLogic = 0;
Element[] e;
FileReader f; // declare a file reader object
Compiler C = new Compiler();
public Element[] Parse(String S){
try{
// Create a new file reader
// connected to S
f = new FileReader(S);
BufferedReader br = new BufferedReader(f);
char[] temp0 = (br.readLine()).toCharArray();
while(!(getWord(temp0,1)).equals("end")){
String type = getWord(temp0,1);
//System.out.println("TYPE is= "+type);
if(type.equals("R")){
element[index] = new Element(C.G,Integer.decode(getWord(temp0,2)).intValue(),
Integer.decode(getWord(temp0,3)).intValue(),-1,-1,
Math.pow(Integer.decode(getWord(temp0,4)).intValue(),-1),-1,-1,-1);
}
else if (type.equals("PORT")){
element[index] = new Element(C.VSRC,0,Integer.decode(getWord(temp0,2)).intValue(),
-1,-1,0,1,Integer.decode(getWord(temp0,4)).intValue(),
Integer.decode(getWord(temp0,3)).intValue());
element[index].MCU = getWord(temp0,5);
}
else if(type.equals("OPAMP")){
element[index] = new Element(C.OpAmp,Integer.decode(getWord(temp0,2)).intValue(),
Integer.decode(getWord(temp0,3)).intValue(),Integer.decode(getWord(temp0,4)).intValue(),
-1,-1,-1,-1,-1);
}
else if(type.equals("AND")){
elementLogic[indexLogic]=new LogicElement(1,Integer.decode(getWord(temp0,2)).intValue(),
Integer.decode(getWord(temp0,3)).intValue(),
Integer.decode(getWord(temp0,4)).intValue());
}
else if(type.equals("OR")){
elementLogic[indexLogic]=new LogicElement(2,Integer.decode(getWord(temp0,2)).intValue(),
Integer.decode(getWord(temp0,3)).intValue(),
Integer.decode(getWord(temp0,4)).intValue());
}
else if(type.equals("NOT")){
elementLogic[indexLogic]=new LogicElement(3,Integer.decode(getWord(temp0,2)).intValue(),
Integer.decode(getWord(temp0,3)).intValue(),1);
}
else if(type.equals("DFF")){
elementLogic[indexLogic]=new LogicElement(4,Integer.decode(getWord(temp0,2)).intValue(),
Integer.decode(getWord(temp0,3)).intValue(),
Integer.decode(getWord(temp0,4)).intValue());
}
else if(type.equals("DUMP")){
int tempIndex = 3;
mcuName[IDIndex] = getWord(temp0,2);
while(!getWord(temp0,tempIndex).equals("ENDDUMP")){
//System.out.println("the word is="+getWord(temp0,tempIndex));
ID[IDIndex] = getWord(temp0,tempIndex);
dataAddr[IDIndex]= Integer.decode(getWord(temp0,(tempIndex+1))).intValue();
IDIndex++;
tempIndex = tempIndex +2;
}
}
else if(type.equals("DUMPLOGIC")){
int tempIndex = 2;
while(!getWord(temp0,tempIndex).equals("ENDDUMP")){
//System.out.println("the word is="+getWord(temp0,tempIndex));
IDLogic[IDIndexLogic] = getWord(temp0,tempIndex);
nodeNumLogic[IDIndexLogic]= Integer.decode(getWord(temp0,(tempIndex+1))).intValue();
IDIndexLogic++;
tempIndex = tempIndex +2;
}
}
else if(type.equals("DUMPANALOG")){
int tempIndex = 2;
while(!getWord(temp0,tempIndex).equals("ENDDUMP")){
//System.out.println("the word is="+getWord(temp0,tempIndex));
IDAnalog[IDIndexAnalog] = getWord(temp0,tempIndex);
nodeNum[IDIndexAnalog]= Integer.decode(getWord(temp0,(tempIndex+1))).intValue();
IDIndexAnalog++;
tempIndex = tempIndex +2;
}
}
else if (type.equals("MCU")){
//System.out.println(getWord(temp0,2));
hexFile = getWord(temp0,2);
}
if((!type.equals("MCU"))&(!type.equals("DUMP"))&(!type.equals("DUMPANALOG"))
&(!type.equals("AND"))&(!type.equals("OR"))&(!type.equals("DFF"))
&(!type.equals("NOT"))&(!type.equals("DUMPLOGIC"))){
index++;
}
if(type.equals("AND")|type.equals("OR")|type.equals("DFF")
|type.equals("NOT")){
//System.out.println("HEREEEEEE9999999999");
indexLogic++;
}
temp0 = (br.readLine()).toCharArray();
}
index--;
indexLogic--;
//System.out.println("INDEX="+index);
e = new Element[index+1];
for(int i = 0; i<e.length; i++){
e[i] = element[i];
}
el = new LogicElement[indexLogic+1];
for(int i = 0; i<el.length; i++){
el[i] = elementLogic[i];
}
}
catch (Exception e){
System.err.println ("Error reading file5555");
}
//System.out.println(e.length);
return e;
}
public String getWord(char[] ch, int wordNum){
boolean endFound = false;
boolean startFound = false;
int wordCount = 0;
int wordStart =0;
int wordEnd = 0;
for(int i = 1; i <ch.length; i++){
//System.out.println("CH length="+ch.length);
if(((ch[i-1]!=' ')&&(ch[i]==' '))|(i ==ch.length-1))
wordCount++;
if((wordCount == wordNum-1)&&(ch[i-1]==' ')&&(ch[i]!=' ')&&!startFound){
wordStart = i;
startFound=true;
}
if((wordCount==wordNum)&&(!endFound)){
if(i==ch.length-1)
wordEnd=i+1;
else
wordEnd=i;
endFound=true;
}
}
//System.out.println("END="+wordEnd+"Start= "+wordStart);
//System.out.println(String.copyValueOf(ch,wordStart,wordEnd-wordStart+1));
return (String.copyValueOf(ch,wordStart,wordEnd-wordStart));
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
public class Solver {
String vars[];// = new String[1];
String varsLogic[];
String varsAnalog[];
VCD vcd = new VCD();
XLS xls = new XLS();
boolean[][] valLogic;
long[][] val;
double[][] valAnalog;
byte PORTCInit = 0;
byte PORTCFinal = 0;
int dummy = 0;//DEBUG*********************************
double temp = 0;//DEBUG*****************************************
long[] cTime = new long[100];//********************Debug
int cTimeIndex = 0;
double tempPort = 0;
public double[] Solve(double[][]A0,double[]z0){
int maxrow;
int n= A0.length;
double tmp;
double[]x = new double[A0.length];
double[][]a = new double[A0.length][A0.length+1];
for(int i = 0; i<A0.length; i++){
for(int j = 0; j<A0.length; j++)
a[i][j]=A0[i][j];
}
for(int i =0; i<A0.length; i++)
a[i][A0.length]=z0[i];
for (int i=0;i<n;i++) {
/* Find the row with the largest first value */
maxrow = i;
for (int j=i+1;j<n;j++) {
if (Math.abs(a[j][i]) > Math.abs(a[maxrow][i]))
maxrow = j;
}
/* Swap the maxrow and ith row */
for (int k=i;k<n+1;k++) {
tmp = a[i][k];
a[i][k] = a[maxrow][k];
a[maxrow][k] = tmp;
}
/* Eliminate the ith element of the jth row */
for (int j=i+1;j<n;j++) {
for (int k=n;k>=i;k--) {
a[j][k] -= a[i][k] * a[j][i] / a[i][i];
}
}
}
/* Do the back substitution */
for (int j=n-1;j>=0;j--) {
tmp = 0;
for (int k=j+1;k<n;k++)
tmp += a[j][k] * x[k];
x[j] = (a[j][n] - tmp) / a[j][j];
}
return x;
}
//Solve a system of non-linear equations for DC analyses using Newton-Raphson algorithm
//where Ax=z, epsilon is a small value to test for convergence, and e is an
//array containing the elements in the circuit
public double[] SolveNL(double[][]A,double[]z, double epsilon, Element[] e){
/* for(int i = 0; i<A.length; i++){
z[i]=0;
for(int j = 0; j<A.length; j++)
A[i][j]=0;
}*/
//Done = true when the solution converges
boolean Done = false;
//noOfNodes in the circuit
int noOfNodes = 0;
//Initialize linear circuit compiler
Compiler C = new Compiler();
//Current results of the NR algorithm
double[] x = new double[A.length];
//Results from the previous iteration of the NR algorithm
double[] xPrev =new double[x.length];
//Find the # of nodes in the circuit & generate linear models of the non-linear elements
//for the next iteration of the NR algorithm
for(int i = 0; i< e.length; i++){
//Determine the number of nodes
if( Math.max( Math.max(e[i].nj,e[i].nk),Math.max(e[i].np,e[i].nq)) > noOfNodes){
noOfNodes = Math.max(Math.max(e[i].nj,e[i].nk),Math.max(e[i].np,e[i].nq));
}
}
for(int i = 0; i< e.length; i++){
//Element processed is a diode
if(e[i].TYPE == C.D){
//Guess the initial diode voltage as 0.7
double vd = 0.7;
//Calculate Gd for this iteration
double Gd = e[i].pnl1*e[i].pnl2*Math.exp(e[i].pnl2*vd);
//Calculate Ids for this iteration
double Ids = e[i].pnl1*(Math.exp(e[i].pnl2*vd)-1)-Gd*vd;
//Generate linear model of the diode for the next iteration
//and update the array of elements
e[i] = new Element(C.D,e[i].nj,e[i].nk,e[i].np,e[i].nq,Gd,Ids,e[i].pnl1,e[i].pnl2);
}
}
//Keep on iterating until the results converge to within +/- epsilon
//of the actual values
while(!Done){
//Compile the circuit using the new element array
A = C.Compile(e,noOfNodes);
//Update previous results
for(int i = 0; i<x.length; i++){
xPrev[i] = x[i];
}
//Get the new results
x = Solve(A,C.z);
//Check for convergence
Done = true;
for(int i =0; i <x.length ; i++){
if(Math.abs(x[i]-xPrev[i])>epsilon)
Done = false;
}
//Process the element list & recompile
for(int i = 0; i< e.length; i++){
//Element processed is a diode
if(e[i].TYPE == C.D){
//Value of the positive terminal voltage
double tempIn = 0;
//Value of the negative terminal voltage
double tempOut = 0;
//voltage accross the diode
double vd = 0;
//Get the voltages on the +/- terminals
if(e[i].nk >0)
tempIn = x[e[i].nk-1];
if(e[i].nj >0)
tempOut = x[e[i].nj-1];
//Calculate diode voltage
vd = tempIn - tempOut;
//Calculate Gd for this iteration
double Gd = e[i].pnl1*e[i].pnl2*Math.exp(e[i].pnl2*vd);
//Calculate Ids for this iteration
double Ids = e[i].pnl1*(Math.exp(e[i].pnl2*vd)-1)-Gd*vd;
//Generate linear model of the diode for the next iteration
//and update the array of elements
e[i] = new Element(C.D,e[i].nj,e[i].nk,e[i].np,e[i].nq,Gd,Ids,e[i].pnl1,e[i].pnl2);
}
}
}
return(x);
}
//Perfrom AC analyses with time-step h
public double[] SolveAC(double[][]A,double[]z, double epsilon, double h, double t, Element[] e,
ADLSimulator MCUs[], String[] ID, int[] addr, int IDIndex,String[] mcuName,
String[] IDAnalog, int[] nodeNum, int IDIndexAnalog,
String[] IDLogic, int[] nodeNumLogic, int IDIndexLogic, Logic logic){
if(IDIndexAnalog!=0)
valAnalog = new double[10001][IDIndexAnalog+1];
else
valAnalog = new double[1][2];
if(IDIndex!=0)
val = new long[IDIndex][10001];
else
val = new long[1][2];
if(IDIndexLogic!=0)
valLogic = new boolean[IDIndexLogic][10001];
else
valLogic = new boolean[1][2];
Element[] element = new Element[e.length];
Compiler C = new Compiler();
double x[] = new double[A.length];
double currentTime = 0;
int noOfNodes = 0;
for(int i = 0; i< element.length; i++){
element[i] = new Element(e[i].TYPE, e[i].nj, e[i].nk, e[i].np, e[i].nq,
e[i].p, e[i].pnl0, e[i].pnl1, e[i].pnl2);
element[i].MCU = e[i].MCU;
}
for(int i = 0; i< e.length; i++){
//Determine the number of nodes
if( Math.max( Math.max(e[i].nj,e[i].nk),Math.max(e[i].np,e[i].nq)) > noOfNodes){
noOfNodes = Math.max(Math.max(e[i].nj,e[i].nk),Math.max(e[i].np,e[i].nq));
}
}
for(int i = 0; i < MCUs.length; i++)
MCUs[0].init();
while(currentTime < t){
for(int i = 0; i<element.length; i++){
//Capacitor
if(element[i].TYPE == C.CAC){
//Temporary variables for calculating capacitor voltage
double tempPlus =0;
double tempMinus = 0;
//Get the voltages on the two nodes connected to
//the capacitor
if(element[i].nj > 0)
tempPlus=x[element[i].nj -1];
if(element[i].nk > 0){
tempMinus = x[element[i].nk - 1];
}
//Subtract the voltages to get Vcap.
double v = tempPlus - tempMinus;
//Generate a new linear capacitor model for the next iteration
//based on the capacitor voltage.
element[i] = new Element(element[i].TYPE, element[i].nj,element[i].nk,element[i].np,element[i].nq,
element[i].p,-1*element[i].p*v,element[i].pnl1,element[i].pnl2);
}
//VAC
if(element[i].TYPE == C.VAC){
temp = Math.cos(currentTime);
element[i] = new Element(element[i].TYPE, element[i].nj,element[i].nk,element[i].np,element[i].nq,
temp,element[i].pnl0,element[i].pnl1,element[i].pnl2);
}
//PORT
if((element[i].TYPE == C.VSRC)&(element[i].pnl0==1)){
ADLSimulator MCU = null;
for(int j = 0; j < MCUs.length; j++){
//String[] s0 = MCUs[j].toString().split("@");
String s1 = MCUs[j].name;//s0[0].substring(7);
// System.out.println(element[i].MCU+"-----------------------------------------element"+j);
// System.out.println(s1+"-----------------------------------------s1");
if(element[i].MCU.equals(s1)){
MCU = MCUs[j];
break;
}
}
//System.out.println("PORT DONE");
if(MCU.getBit(MCU.DMEM[(byte)element[i].pnl2],(int)element[i].pnl1)){
tempPort = 5;
}
else{
tempPort = 0;
}
String mcu = element[i].MCU;
element[i] = new Element(element[i].TYPE,element[i].nj,element[i].nk,element[i].np,element[i].nq,
tempPort,element[i].pnl0,element[i].pnl1,element[i].pnl2);
element[i].MCU = mcu;
}
}
/*******INITIAL Values of PORTC*******/
// PORTCInit = MCU.regFileIO[21];
/***********************************/
for(int i = 0 ; i < MCUs.length; i++){
if (currentTime >= MCUs[i].cycleNum) {
MCUs[i].run();
}
}
/*******FINAL Value of PORTC*******/
// PORTCFinal = MCU.regFileIO[21];
/***********************************/
double tempX = x[17];
A = C.Compile(element,noOfNodes);
x = SolveNL(A,C.z,epsilon,element);
// x = Solve(A,C.z);
currentTime = currentTime + h;
dummy++;
//System.out.println("TEST");
///*****HANDLE DUMPS***********************////////////
String propogate = null;
for(int i = 0 ; i < mcuName.length; i++){
if(mcuName[i] != null){
propogate = mcuName[i];
}
else{
mcuName[i] = propogate;
}
}
if(IDIndex!=0){
for(int i=0; i<IDIndex; i++){
ADLSimulator MCU = null;
//System.out.println(mcuName[i]);
for(int j = 0; j < MCUs.length; j++){
if(MCUs[j].name.equals(mcuName[i]))
MCU = MCUs[j];
}
//System.out.println(MCU);
val[i][(int)currentTime]=MCU.DMEM[addr[i]];
}
}
/********LOGIC******/
if(IDIndexLogic!=0){
for(int i = 0; i<logic.externalInputs.length; i++){
// System.out.println("EXT[i]="+logic.externalInputs[i]);
}
//System.out.println("****************************************************");
boolean[] newLogicVals= new boolean[logic.oldNodeVals.length];
for(int i = 0; i<newLogicVals.length;i++){
newLogicVals[i] = logic.oldNodeVals[i];
}
for(int i = 0; i<logic.externalInputs.length; i++){
if(logic.externalInputs[i]&(i==0)){
newLogicVals[i] = false;
}
if(logic.externalInputs[i]&(i<x.length)&(i>0)){
newLogicVals[i] = (x[i-1]>3.5);
}
}
boolean currentVals[] = logic.SolveLogic(newLogicVals);
for(int i= 0; i<IDIndexLogic;i++){
valLogic[i][(int)currentTime-1] = currentVals[nodeNumLogic[i]];
}
}
/*******************/
// if(analogMode==0){
if(IDIndexAnalog!=0){
valAnalog[(int)currentTime][0]=currentTime;
for(int i=1; i<IDIndexAnalog+1; i++){
valAnalog[(int)currentTime][i]=x[nodeNum[i-1]-1];
}
}
}
for(int i = 0; i <MCUs.length; i++)
MCUs[i].finish();
if(IDIndex!=0){
vars = new String[IDIndex];
//System.out.println("IDINDEX="+IDIndex);
for(int i = 0;i<IDIndex;i++){
vars[i] = ID[i];
}
if(IDIndexLogic!=0){
varsLogic = new String[IDIndexLogic];
//System.out.println("IDINDEX="+IDIndex);
for(int i = 0;i<IDIndexLogic;i++){
varsLogic[i] = IDLogic[i];
}
vcd.makeVCD(vars,varsLogic,val,valLogic,"VCDRESULTS.vcd");
}
else
vcd.makeVCD(vars,val,"VCDRESULTS.vcd");
}
/*****makevcd*****/
/******makexls****/
varsAnalog = new String[IDIndexAnalog+1];
varsAnalog[0] = "Time";
for(int i = 1;i<IDIndexAnalog+1;i++){
varsAnalog[i] = IDAnalog[i-1];
}
xls.makeXLS(varsAnalog,valAnalog,"XLSRESULTS.xls");
/******makexls****/
return x;
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
import java.io.*;
public class VCD {
ADLSimulator MCU= new ADLSimulator();
FileOutputStream f;
//Return a string representing the binary equivalent of n
public String decimalToBinary(int n){
String S = "";
for(int i = 31; i>=0; i--){
if(MCU.getBit(n,i))
S = S + "1";
else
S = S + "0";
}
return S;
}
//Return a string representing the binary equivalent of n
public String decimalToBinary(long n){
String S = "";
for(int i = 63; i>=0; i--){
if(MCU.getBit(n,i))
S = S + "1";
else
S = S + "0";
}
return S;
}
/*******OVERLOADED METHOD**************/
//Create a VCD file given an array of values and a file name
public void makeVCD(String[] vars,String[]varsLogic,long[][] val,boolean[][] valLogic, String S){
try{
f = new FileOutputStream(S);
PrintStream pr = new PrintStream(f);
pr.println("$timescale");
pr.println("1 ns");
pr.println("$end");
for(int i=0;i<vars.length;i++){
pr.println("$var reg 8 "+vars[i]+" "+vars[i]+" "+"$end");
}
for(int i=0;i<varsLogic.length;i++){
pr.println("$var reg 1 "+varsLogic[i]+" "+varsLogic[i]+" "+"$end");
}
pr.println("$dumpvars");
for(int cycleIndex=0; cycleIndex< val[0].length;cycleIndex++){
if(cycleIndex!=0){
pr.println("#"+cycleIndex);
}
for(int valIndex= 0; valIndex < val.length; valIndex++){
pr.println("b"+decimalToBinary(val[valIndex][cycleIndex])+" "+vars[valIndex]);
}
for(int valLogicIndex= 0; valLogicIndex < valLogic.length; valLogicIndex++){
if(valLogic[valLogicIndex][cycleIndex])
pr.println("b1 "+varsLogic[valLogicIndex]);
else
pr.println("b0 "+varsLogic[valLogicIndex]);
}
}
pr.println("$end");
}
catch (Exception e){
System.err.println ("Error writing file");
}
}
//Create a VCD file given an array of values and a file name
public void makeVCD(String[] vars,long[][] val, String S){
try{
f = new FileOutputStream(S);
PrintStream pr = new PrintStream(f);
pr.println("$timescale");
pr.println("1 ns");
pr.println("$end");
for(int i=0;i<vars.length;i++){
pr.println("$var reg 8 "+vars[i]+" "+vars[i]+" "+"$end");
}
pr.println("$dumpvars");
for(int cycleIndex=0; cycleIndex< val[0].length;cycleIndex++){
if(cycleIndex!=0){
pr.println("#"+cycleIndex);
}
for(int valIndex= 0; valIndex < val.length; valIndex++){
pr.println("b"+decimalToBinary(val[valIndex][cycleIndex])+" "+vars[valIndex]);
}
}
pr.println("$end");
}
catch (Exception e){
System.err.println ("Error writing file");
}
}
}
package adlsim;
/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: </p>
* @author unascribed
* @version 1.0
*/
import java.io.*;
public class XLS {
ADLSimulator MCU= new ADLSimulator();
FileOutputStream f;
//Create an XLS file given an array of values and a file name
public void makeXLS(String[] vars,double[][] val, String S){
try{
f = new FileOutputStream(S);
PrintStream pr = new PrintStream(f);
for(int i=0; i < vars.length; i++){
pr.print(vars[i]+'\t');
}
pr.println();
for(int cycleIndex = 0; cycleIndex < val.length; cycleIndex++){
for(int varIndex = 0; varIndex <val[0].length; varIndex++){
pr.print(val[cycleIndex][varIndex]);
pr.print('\t');
}
pr.println();
}
}
catch (Exception e){
System.err.println ("Error writing file5555555555555555555");
}
}
}