From f483ee2c38c1a35be3533c9433f7375235295d10 Mon Sep 17 00:00:00 2001 From: "rajshekar.k" Date: Mon, 26 Aug 2019 11:41:36 +0530 Subject: [PATCH] files added --- build.xml | 44 +++++ src/configuration/Configuration.java | 116 ++++++++++++ src/configuration/config.xml | 43 +++++ src/generic/Instruction.java | 96 ++++++++++ src/generic/Misc.java | 10 + src/generic/Operand.java | 41 ++++ src/generic/ParsedProgram.java | 268 +++++++++++++++++++++++++++ src/generic/Simulator.java | 28 +++ src/generic/Statistics.java | 13 ++ src/main/Main.java | 19 ++ 10 files changed, 678 insertions(+) create mode 100644 build.xml create mode 100644 src/configuration/Configuration.java create mode 100644 src/configuration/config.xml create mode 100644 src/generic/Instruction.java create mode 100644 src/generic/Misc.java create mode 100644 src/generic/Operand.java create mode 100644 src/generic/ParsedProgram.java create mode 100644 src/generic/Simulator.java create mode 100644 src/generic/Statistics.java create mode 100644 src/main/Main.java diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..f8164cd --- /dev/null +++ b/build.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/configuration/Configuration.java b/src/configuration/Configuration.java new file mode 100644 index 0000000..d7b43e1 --- /dev/null +++ b/src/configuration/Configuration.java @@ -0,0 +1,116 @@ +package configuration; + +import java.io.File; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import generic.Misc; + +public class Configuration { + public static int ALU_count; + public static int ALU_latency; + public static int ALU_reciprocal_of_throughput; + public static int multiplier_count; + public static int multiplier_latency; + public static int multiplier_reciprocal_of_throughput; + public static int divider_count; + public static int divider_latency; + public static int divider_reciprocal_of_throughput; + + public static int L1i_numberOfLines; + public static int L1i_latency; + public static int L1i_associativity; + public static String L1i_replacementPolicy; + + public static int L1d_numberOfLines; + public static int L1d_latency; + public static int L1d_associativity; + public static String L1d_replacementPolicy; + + public static int L2_numberOfLines; + public static int L2_latency; + public static int L2_associativity; + public static String L2_replacementPolicy; + + public static int mainMemoryLatency; + + public static void parseConfiguratioFile(String configFileName) + { + Document doc = null; + + try + { + File file = new File(configFileName); + DocumentBuilderFactory DBFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder DBuilder = DBFactory.newDocumentBuilder(); + doc = DBuilder.parse(file); + doc.getDocumentElement().normalize(); + } + catch(Exception e) + { + e.printStackTrace(); + Misc.printErrorAndExit("Error in reading config file : " + e); + } + + NodeList nodeLst = doc.getElementsByTagName("ALU"); + Element elmnt = (Element) nodeLst.item(0); + ALU_count = Integer.parseInt(getImmediateString("Count", elmnt)); + ALU_latency = Integer.parseInt(getImmediateString("Latency", elmnt)); + ALU_reciprocal_of_throughput = Integer.parseInt(getImmediateString("ReciprocalOfThroughput", elmnt)); + + nodeLst = doc.getElementsByTagName("Multiplier"); + elmnt = (Element) nodeLst.item(0); + multiplier_count = Integer.parseInt(getImmediateString("Count", elmnt)); + multiplier_latency = Integer.parseInt(getImmediateString("Latency", elmnt)); + multiplier_reciprocal_of_throughput = Integer.parseInt(getImmediateString("ReciprocalOfThroughput", elmnt)); + + nodeLst = doc.getElementsByTagName("Divider"); + elmnt = (Element) nodeLst.item(0); + divider_count = Integer.parseInt(getImmediateString("Count", elmnt)); + divider_latency = Integer.parseInt(getImmediateString("Latency", elmnt)); + divider_reciprocal_of_throughput = Integer.parseInt(getImmediateString("ReciprocalOfThroughput", elmnt)); + + nodeLst = doc.getElementsByTagName("L1iCache"); + elmnt = (Element) nodeLst.item(0); + L1i_numberOfLines = Integer.parseInt(getImmediateString("NumberOfLines", elmnt)); + L1i_latency = Integer.parseInt(getImmediateString("Latency", elmnt)); + L1i_associativity = Integer.parseInt(getImmediateString("Associativity", elmnt)); + L1i_replacementPolicy = getImmediateString("ReplacementPolicy", elmnt); + + nodeLst = doc.getElementsByTagName("L1dCache"); + elmnt = (Element) nodeLst.item(0); + L1d_numberOfLines = Integer.parseInt(getImmediateString("NumberOfLines", elmnt)); + L1d_latency = Integer.parseInt(getImmediateString("Latency", elmnt)); + L1d_associativity = Integer.parseInt(getImmediateString("Associativity", elmnt)); + L1d_replacementPolicy = getImmediateString("ReplacementPolicy", elmnt); + + nodeLst = doc.getElementsByTagName("L2Cache"); + elmnt = (Element) nodeLst.item(0); + L2_numberOfLines = Integer.parseInt(getImmediateString("NumberOfLines", elmnt)); + L2_latency = Integer.parseInt(getImmediateString("Latency", elmnt)); + L2_associativity = Integer.parseInt(getImmediateString("Associativity", elmnt)); + L2_replacementPolicy = getImmediateString("ReplacementPolicy", elmnt); + + nodeLst = doc.getElementsByTagName("Configuration"); + elmnt = (Element) nodeLst.item(0); + mainMemoryLatency = Integer.parseInt(getImmediateString("MainMemoryLatency", elmnt)); + } + + private static String getImmediateString(String tagName, Element parent) // Get the immediate string value of a particular tag name under a particular parent tag + { + NodeList nodeLst = parent.getElementsByTagName(tagName); + if (nodeLst.item(0) == null) + { + Misc.printErrorAndExit("XML Configuration error : Item \"" + tagName + "\" not found inside the \"" + parent.getTagName() + "\" tag in the configuration file!!"); + } + Element NodeElmnt = (Element) nodeLst.item(0); + NodeList resultNode = NodeElmnt.getChildNodes(); + return ((Node) resultNode.item(0)).getNodeValue(); + } +} diff --git a/src/configuration/config.xml b/src/configuration/config.xml new file mode 100644 index 0000000..002c97c --- /dev/null +++ b/src/configuration/config.xml @@ -0,0 +1,43 @@ + + + + + 2 + 1 + 1 + + + 1 + 4 + 1 + + + 1 + 10 + 1 + + + + + 256 + 2 + 4 + LRU + + + + 256 + 2 + 4 + LRU + + + + 2048 + 10 + 4 + LRU + + + 40 + \ No newline at end of file diff --git a/src/generic/Instruction.java b/src/generic/Instruction.java new file mode 100644 index 0000000..ec3ef99 --- /dev/null +++ b/src/generic/Instruction.java @@ -0,0 +1,96 @@ +package generic; + +public class Instruction { + + public enum OperationType {add, addi, sub, subi, mul, muli, div, divi, and, andi, or, ori, xor, xori, slt, slti, sll, slli, srl, srli, sra, srai, load, store, jmp, beq, bne, blt, bgt, end}; + + int programCounter; + OperationType operationType; + Operand sourceOperand1; + Operand sourceOperand2; + Operand destinationOperand; + + public int getProgramCounter() { + return programCounter; + } + public void setProgramCounter(int programCounter) { + this.programCounter = programCounter; + } + public OperationType getOperationType() { + return operationType; + } + public void setOperationType(OperationType operationType) { + this.operationType = operationType; + } + public Operand getSourceOperand1() { + return sourceOperand1; + } + public void setSourceOperand1(Operand sourceOperand1) { + this.sourceOperand1 = sourceOperand1; + } + public Operand getSourceOperand2() { + return sourceOperand2; + } + public void setSourceOperand2(Operand sourceOperand2) { + this.sourceOperand2 = sourceOperand2; + } + public Operand getDestinationOperand() { + return destinationOperand; + } + public void setDestinationOperand(Operand destinationOperand) { + this.destinationOperand = destinationOperand; + } + public String toString() + { + if(sourceOperand1 != null) + { + if(sourceOperand2 != null) + { + if(destinationOperand != null) + { + return "PC="+ programCounter + "\t" + operationType + "\t" + sourceOperand1 + "\t" + sourceOperand2 + "\t" + destinationOperand + "\n"; + } + else + { + return "PC="+ programCounter + "\t" + operationType + "\t" + sourceOperand1 + "\t" + sourceOperand2 + "\tnull" + "\n"; + } + } + else + { + if(destinationOperand != null) + { + return "PC="+ programCounter + "\t" + operationType + "\t" + sourceOperand1 + "\tnull" + "\t" + destinationOperand + "\n"; + } + else + { + return "PC="+ programCounter + "\t" + operationType + "\t" + sourceOperand1 + "\tnull" + "\tnull" + "\n"; + } + } + } + else + { + if(sourceOperand2 != null) + { + if(destinationOperand != null) + { + return "PC="+ programCounter + "\t" + operationType + "\tnull" + "\t" + sourceOperand2 + "\t" + destinationOperand + "\n"; + } + else + { + return "PC="+ programCounter + "\t" + operationType + "\tnull" + "\t" + sourceOperand2 + "\tnull" + "\n"; + } + } + else + { + if(destinationOperand != null) + { + return "PC="+ programCounter + "\t" + operationType + "\tnull" + "\tnull" + "\t" + destinationOperand + "\n"; + } + else + { + return "PC="+ programCounter + "\t" + operationType + "\tnull" + "\tnull" + "\tnull" + "\n"; + } + } + } + } +} diff --git a/src/generic/Misc.java b/src/generic/Misc.java new file mode 100644 index 0000000..0be690a --- /dev/null +++ b/src/generic/Misc.java @@ -0,0 +1,10 @@ +package generic; + +public class Misc { + + public static void printErrorAndExit(String message) + { + System.err.println(message); + System.exit(1); + } +} diff --git a/src/generic/Operand.java b/src/generic/Operand.java new file mode 100644 index 0000000..3224099 --- /dev/null +++ b/src/generic/Operand.java @@ -0,0 +1,41 @@ +package generic; + +public class Operand { + + public enum OperandType {Register, Immediate, Label}; + + OperandType operandType; + int value; + String labelValue; //only applicable for Label type; + //Note that Label type is only applicable for functional emulation of assembly file + + public OperandType getOperandType() { + return operandType; + } + public void setOperandType(OperandType operandType) { + this.operandType = operandType; + } + public int getValue() { + return value; + } + public void setValue(int value) { + this.value = value; + } + public String getLabelValue() { + return labelValue; + } + public void setLabelValue(String labelValue) { + this.labelValue = labelValue; + } + public String toString() + { + if(operandType == OperandType.Register || operandType == OperandType.Immediate) + { + return "[" + operandType.toString() + ":" + value + "]"; + } + else + { + return "[" + operandType.toString() + ":" + labelValue + "]"; + } + } +} diff --git a/src/generic/ParsedProgram.java b/src/generic/ParsedProgram.java new file mode 100644 index 0000000..7cc69f0 --- /dev/null +++ b/src/generic/ParsedProgram.java @@ -0,0 +1,268 @@ +package generic; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Scanner; +import java.util.regex.Pattern; +import generic.Instruction.OperationType; +import generic.Operand.OperandType; + +public class ParsedProgram { + static ArrayList code = new ArrayList(); + static int mainFunctionAddress; + static int firstCodeAddress; + static ArrayList data = new ArrayList(); + + public static void setMainFunctionAddress(int addr) + { + mainFunctionAddress = addr; + } + + public static void setFirstCodeAddress(int addr) + { + firstCodeAddress = addr; + } + + public static Instruction getInstructionAt(int programCounter) + { + return code.get(programCounter - firstCodeAddress); + } + + + static HashMap symtab = new HashMap(); + + + public static int parseDataSection(String assemblyProgramFile) + { + FileInputStream inputStream = null; + try + { + inputStream = new FileInputStream(assemblyProgramFile); + } + catch(FileNotFoundException e) { + Misc.printErrorAndExit(e.toString()); + } + + Scanner sc=new Scanner(inputStream); + int address = 0; //Store data staring from 1st memory location. At 0th location we denote the start of the code section. + + + while(sc.hasNextLine()) //TODO 3 loops? + { + String line=sc.nextLine(); + + if(line.contains(".data")) //Processing the .data section + { + line=sc.next(); + + do + { + if(Pattern.matches("[a-zA-Z]+([0-9]*)(:)", line)) + { + ParsedProgram.symtab.put(line.replaceAll("[^a-zA-Z]",""), address);//TODO removed statements that were adding data to the code arraylist + + while(Pattern.matches("-?\\d+", line=sc.next())) + { + data.add(Integer.parseInt(line)); + address++; + + } + } + }while(!line.contains(".text")); + + break; + } + } + + sc.close(); + + setFirstCodeAddress(address); + + return address; + } + + public static void parseCodeSection(String assemblyProgramFile, int firstCodeAddress) + { + FileInputStream inputStream = null; + try + { + inputStream = new FileInputStream(assemblyProgramFile); + } + catch(FileNotFoundException e) { + Misc.printErrorAndExit(e.toString()); + } + + Scanner sc=new Scanner(inputStream); + int address = firstCodeAddress; + + while(sc.hasNextLine()) + { + String line=sc.nextLine(); + if(line.contains(".text")) + { + break; + } + } + + while(sc.hasNextLine()) + { + String line; + if(Pattern.matches("[a-zA-Z]+([0-9]*)(:)", line=sc.nextLine())) + { + ParsedProgram.symtab.put(line.replaceAll(":",""), address); + if(line.replaceAll(":","").compareTo("main") == 0) + { + ParsedProgram.setMainFunctionAddress(address); + } + } + else + { + ParsedProgram.code.add(address-firstCodeAddress, getInstructionFromString(line, address)); + address++; + } + } + sc.close(); + } + + private static Instruction getInstructionFromString(String line, int address) + { + Instruction newInstruction = new Instruction(); + newInstruction.setProgramCounter(address); + + Scanner sc = new Scanner(line); + newInstruction.setOperationType(OperationType.valueOf(sc.next())); + + switch(newInstruction.getOperationType()) + { + //R3I type + case add : + case sub : + case mul : + case div : + case and : + case or : + case xor : + case slt : + case sll : + case srl : + case sra : { + newInstruction.setSourceOperand1(getRegisterOperandFromString(sc.next())); + newInstruction.setSourceOperand2(getRegisterOperandFromString(sc.next())); + newInstruction.setDestinationOperand(getRegisterOperandFromString(sc.next())); + break; + } + + //R2I type + case addi : + case subi : + case muli : + case divi : + case andi : + case ori : + case xori : + case slti : + case slli : + case srli : + case srai : + case load : + case store : { + newInstruction.setSourceOperand1(getRegisterOperandFromString(sc.next())); + String str = sc.next(); + if(Pattern.matches("-?\\d+(,)",str)) + { + //absolute immediate + newInstruction.setSourceOperand2(getImmediateOperandFromString(str)); + } + else + { + //label / symbol + newInstruction.setSourceOperand2(getLabelOperandFromString(str)); + } + newInstruction.setDestinationOperand(getRegisterOperandFromString(sc.next())); + break; + } + + case beq : + case bne : + case blt : + case bgt : { + newInstruction.setSourceOperand1(getRegisterOperandFromString(sc.next())); + newInstruction.setSourceOperand2(getRegisterOperandFromString(sc.next())); + String str = sc.next(); + if(Pattern.matches("[0-9]+(,)",str)) + { + //absolute immediate + newInstruction.setDestinationOperand(getImmediateOperandFromString(str)); + } + else + { + //label / symbol + newInstruction.setDestinationOperand(getLabelOperandFromString(str)); + } + break; + } + + //RI type : + case jmp : { + String str = sc.next(); + if(Pattern.matches("[0-9]+(,)",str)) + { + //absolute immediate + newInstruction.setDestinationOperand(getImmediateOperandFromString(str)); + } + else if(Pattern.matches("%x([0-9]{1,2})",str)) { + newInstruction.setDestinationOperand(getRegisterOperandFromString(str)); + } + else + { + //label / symbol + newInstruction.setDestinationOperand(getLabelOperandFromString(str)); + } + break; + } + + case end : break; + + default: Misc.printErrorAndExit("unknown instruction!!"); + } + + sc.close(); + + return newInstruction; + } + + private static Operand getRegisterOperandFromString(String str) + { + Operand operand = new Operand(); + operand.setOperandType(OperandType.Register); + operand.setValue(Integer.parseInt(str.replaceAll("[^0-9]", ""))); + return operand; + } + + private static Operand getImmediateOperandFromString(String str) + { + Operand operand = new Operand(); + operand.setOperandType(OperandType.Immediate); + operand.setValue(Integer.parseInt(str.replaceAll("[^-?\\d+]",""))); + return operand; + } + + private static Operand getLabelOperandFromString(String str) + { + Operand operand = new Operand(); + operand.setOperandType(OperandType.Label); + operand.setLabelValue(str.replaceAll("[$,]", "")); + return operand; + } + + static void printState() + { + System.out.println("Symbol Table :"); + System.out.println(Arrays.asList(symtab)); + System.out.println("\nParsed instructions :"); + System.out.println(Arrays.asList(code)); + } +} diff --git a/src/generic/Simulator.java b/src/generic/Simulator.java new file mode 100644 index 0000000..2f8777a --- /dev/null +++ b/src/generic/Simulator.java @@ -0,0 +1,28 @@ +package generic; + +import java.io.FileInputStream; +import generic.Operand.OperandType; + + +public class Simulator { + + static FileInputStream inputcodeStream = null; + + public static void setupSimulation(String assemblyProgramFile) + { + int firstCodeAddress = ParsedProgram.parseDataSection(assemblyProgramFile); + ParsedProgram.parseCodeSection(assemblyProgramFile, firstCodeAddress); + ParsedProgram.printState(); + } + + public static void assemble(String objectProgramFile) + { + //TODO your assembler code + //1. open the objectProgramFile in binary mode + //2. write the firstCodeAddress to the file + //3. write the data to the file + //4. assemble one instruction at a time, and write to the file + //5. close the file + } + +} diff --git a/src/generic/Statistics.java b/src/generic/Statistics.java new file mode 100644 index 0000000..059cb7a --- /dev/null +++ b/src/generic/Statistics.java @@ -0,0 +1,13 @@ +package generic; + +public class Statistics { + + // TODO add your statistics here + + // TODO write functions to update statistics + + public static void printStatistics(String statFile) + { + // TODO add code here to print statistics in the output file + } +} diff --git a/src/main/Main.java b/src/main/Main.java new file mode 100644 index 0000000..fcb74c3 --- /dev/null +++ b/src/main/Main.java @@ -0,0 +1,19 @@ +package main; +import configuration.Configuration; +import generic.Misc; +import generic.Statistics; +import generic.Simulator; + +public class Main { + + public static void main(String[] args) { + if(args.length != 2) + { + Misc.printErrorAndExit("usage: java -jar \n"); + } + + Simulator.setupSimulation(args[0]); + Simulator.assemble(args[1]); + } + +}