import java.io.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.event.*;
import java.util.*;
public class Project extends JFrame implements ActionListener
{
private int size, assoc, blocksize,nSets,nBlock,tmp,nindex,taglength,temporary,x;
private int writeCount,missCount,readCount,length,num;
private Integer address;
private double tagLength,noSets,noBlock,nIndex;
private BufferedReader inData;
private JTextField[] JT = new JTextField[8];
private String line,tag,index,block,binAdd,temp,action,tp;
private String memory[],mem[][];
private StringTokenizer st;
public Project()
{
// Initialize GUI
setTitle("Cache Simulator");
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container pane = getContentPane();
pane.setLayout(new GridLayout(10,1));
// Initialize JPanels
JPanel panel[] = new JPanel[10];
// Initialize JLabels
JLabel[] label = new JLabel[9];
label[0] = new JLabel("Enter the filename");
label[1] = new JLabel("Enter the size of the cache in bytes: ");
label[2] = new JLabel("Enter the associativity: ");
label[3] = new JLabel("Enter the blocksize in bytes: ");
label[4] = new JLabel("Results of Simulation");
label[5] = new JLabel("Number of L1 reads: ");
label[6] = new JLabel("Number of L1 read misses: ");
label[7] = new JLabel("Number of L1 writes: ");
label[8] = new JLabel("L1 Miss rate: ");
for(int i=0;i<4;i++) //Add the labels and text boxes to the GUI
{
panel[i]=new JPanel(new GridLayout(1,2));
JT[i] = new JTextField("",4);
JT[i].setHorizontalAlignment(JTextField.CENTER);
JT[i].setFont(new Font("", Font.PLAIN, 12));
panel[i].add(label[i]);
panel[i].add(JT[i]);
pane.add(panel[i]);
}
panel[4]=new JPanel(new BorderLayout());
JButton go = new JButton("Go"); //Make a button to start the simulation
go.addActionListener(this);
panel[4].add(go);
pane.add(panel[4]);
panel[5]=new JPanel(new FlowLayout());
panel[5].add(label[4],BorderLayout.CENTER);
pane.add(panel[5]);
for(int i=5;i<9;i++) //Add the remaining labels and text boxes to the GUI
{
panel[i+1]=new JPanel(new GridLayout(1,2));
JT[i-1] = new JTextField("",4);
JT[i-1].setHorizontalAlignment(JTextField.CENTER);
JT[i-1].setFont(new Font("", Font.PLAIN, 12));
panel[i+1].add(label[i]);
panel[i+1].add(JT[i-1]);
pane.add(panel[i+1]);
}
for(int i=4;i<8;i++)
{
JT[i].setEditable(false);
JT[i].setBackground(new Color(255,255,255));
}
}
public static void main(String[] args)
{
Project p = new Project();
p.pack();
p.setVisible(true);
}
public void actionPerformed(ActionEvent ev) //hey look, the buttons work
{
readCount=0;
writeCount=0;
missCount=0;
if(JT[0].getText().equals(""))
JT[0].setText("trace.txt");
if(JT[1].getText().equals(""))
JT[1].setText("2048");
size = Integer.parseInt(JT[1].getText().trim());
if(JT[2].getText().equals(""))
JT[2].setText("4");
for(int i=0;i<4;i++) //Make sure the inputs are above zero
{
if(JT[i].getText().equals("0")||JT[i].getText().contains("-"))
{
JOptionPane.showMessageDialog(null,"Zero or negatives are not valid values.");
System.exit(0);
}
}
assoc = Integer.parseInt(JT[2].getText().trim());
memory = new String[size]; //array for cache with an associativity of 1
mem = new String[size][assoc]; //Array for cache with an associativity greater than 1
if(JT[3].getText().equals(""))
JT[3].setText("32");
blocksize = Integer.parseInt(JT[3].getText().trim());
//Find number of sets
noSets = size/(blocksize * assoc);
if((noSets-(int)noSets) >=.5)
nSets = (int)noSets+1;
else
nSets = (int)noSets;
nIndex = Math.log(nSets)/Math.log(2);
nindex = (int)nIndex;
double test = nSets%2;
if(test == 1)
nSets+=1;
//Find block offset
noBlock = Math.log(blocksize)/Math.log(2);
if((noBlock-(int)noBlock) >=.5)
nBlock=(int)noBlock+1;
else
nBlock=(int)noBlock;
tagLength = 32 - nBlock - nIndex;
taglength = (int)tagLength;
try {
inData = new BufferedReader(new FileReader(JT[0].getText().trim()));
line = inData.readLine();
}
catch(FileNotFoundException e)
{
JOptionPane.showMessageDialog(null,"File not Found");
}
catch(IOException e)
{
JOptionPane.showMessageDialog(null,"Error reading file");
}
for(int i=0;i<size;i++) //Initialize the array to be blank
{
memory[i]="";
}
for(int i=0;i<size;i++) //Initialize the array for associativity over 1 to blank
{
for(int j=0;j<assoc;j++)
{
mem[i][j]="";
}
}
while(line != null)
{
action = new String(""+line.charAt(0)); //Determine if the operation is read or write
temp = new String(""+line.substring(1).trim()); //Pull off the address
address = Integer.parseInt(temp, 16); //Make the address a number
binAdd = Integer.toBinaryString(address); //Turn the address into binary
while(binAdd.length()<32) //Make sure the address is 32 bits long
{
binAdd= "0"+binAdd;
}
tmp = Integer.parseInt(binAdd.substring(0,taglength),2);
tag = Integer.toHexString(tmp); //Pull off the tag
while(tag.length()<taglength/8) //Make sure the tag is the correct length
{
tag= "0"+tag;
}
tmp = Integer.parseInt(binAdd.substring(taglength,taglength+nindex),2);
index = Integer.toHexString(tmp); //Store the value for the index
tmp = Integer.parseInt(index,16);
temporary=readCount+writeCount; //LRU Counter
if(action.equals("r")&&assoc == 1) //Read with associativity of 1
{
if(!memory[tmp].contains(tag))
missCount++;
memory[tmp]=tag+" "+readCount;
readCount++;
}
else if(action.equals("r")&& assoc != 1) //Its a read
{
int i=0;
for(i=0;i<assoc;i++) //Look for the tag in memory
{
if(mem[tmp][i].contains(tag))
{
action="";
break;
}
else {
action="m";
}
}
if(!action.equals("m")) //Its a hit
{
mem[tmp][i]=tag+" "+readCount;
}
else //Its a miss
{
String s;
num=0;
missCount++;
int k=0;
if(!mem[tmp][0].equals(""))
{
for(int j=1;j<assoc;j++)
{
if(mem[tmp][j].equals(""))
{
k=j;
break;
}
}
//No empty blocks were found
if(k==0)
{
st = new StringTokenizer(mem[tmp][0]);
st.nextToken();
int LRU=Integer.parseInt(st.nextToken().trim());
for(int j=1;j<assoc;j++) //get the lowest LRU number
{
st = new StringTokenizer(mem[tmp][j]);
st.nextToken();
s=st.nextToken();
if(LRU > Integer.parseInt(s))
{
LRU=Integer.parseInt(s);
k=j;
}
}
}
}
mem[tmp][k]=""+tag+" "+temporary; //write the new tag
}
readCount++;
}
else if(assoc!=1&& action.equals("")) { //Its a write with associativity greater than one
int k=0;
writeCount++;
if(!mem[tmp][0].equals(""))
{
int j;
for(j=0;j<assoc;j++)
{
if(mem[tmp][j].contains(""+tag))
{
k=j;
} }
if(j==assoc)
k=0;
mem[tmp][k]=""+tag+" "+temporary;
}
}
else //Its a write with an associativity of 1
writeCount++;
try {
line = inData.readLine();
}
catch(IOException e) {
JOptionPane.showMessageDialog(null,"Error reading file");
}
}
JT[4].setText(""+readCount);
JT[5].setText(""+missCount);
JT[6].setText(""+writeCount);
tp = ""+(double)missCount/readCount;
if(tp.length()>4)
tp = tp.substring(0,6);
JT[7].setText(tp);
} }