This commit is contained in:
Aadi Desai 2020-06-04 15:05:17 +01:00
commit 12bd671c00

View file

@ -1,8 +1,27 @@
/*
Source code for generating MIF files from instructions
Input format: Text file with each instruction on a seperate line (see below, please follow this new lines breeak this code);
Output format: Use stdout to redirect to filename.mif or filename.txt and then convert to .mif
Single instruction format and example:
1. INSTRUCTION RD RS1 RS2 (all in capitals, seperated by whitespace (this is okay if not exact, code removes whitespace anyway),
BUT MUST INCLUDE R for registers)
example: AND R2 R4 R5
MUL R0 R4 R7
JMP R2
STP
For instructions that use only two registers, example MOV: MOV R0 R1 (do not enter third register, just proceed to next instruction)
For instructions that use one register, example JMP: JMP R0 (similar to before, just proceed to next instruction)
For insturctions that use no registers, example STP: STP (and just proceed to next line)
2. LDA/STA RN MEMORY_LOCATION(DECIMAL) (please make sure memory location is in DECIMAL, otherwise bad things happen with the code)
example: LDA R3 1546
STA R6 909
*/
#include <iostream> #include <iostream>
#include <sstream>
#include <string> #include <string>
#include <vector> #include <vector>
#include <cassert> #include <cassert>
#include <algorithm>
using namespace std; using namespace std;
@ -14,17 +33,6 @@ using namespace std;
const unsigned int RAM_SIZE = 2048; const unsigned int RAM_SIZE = 2048;
const unsigned int INSTRUCTION_LENGTH = 16; const unsigned int INSTRUCTION_LENGTH = 16;
vector<string> getWords(string line){
vector<string> ans;
istringstream stream(line);
while (stream){
string temp;
stream >> temp;
ans.pb(temp);
}
return ans;
}
string convertBinaryToHex(string binary4){ string convertBinaryToHex(string binary4){
if(binary4=="0000"){ if(binary4=="0000"){
return "0"; return "0";
@ -59,45 +67,200 @@ string convertBinaryToHex(string binary4){
}else if(binary4=="1111"){ }else if(binary4=="1111"){
return "F"; return "F";
}else{ }else{
cerr << "Invalide binary quartet, cannot convert to HEX (line 78 in .cpp file)" << endl;
assert(0); assert(0);
} }
} }
string convertDecimalToBinary(int decimal, int digits){
if (decimal>2047){
cerr << "Too large memory location, we don't have that much memory for LDA/STA" << endl;
assert(0);
}
string ans="";
while(decimal>0){
int rem = decimal%2;
ans+=to_string(rem);
decimal/=2;
}
while(ans.size()<digits){
ans+="0";
}
reverse(ans.begin(), ans.end());
return ans;
}
string convertInstructionToHex(string binaryInstruction){ string convertInstructionToHex(string binaryInstruction){
string ans=""; string ans="";
string temp=""; string temp="";
assert(binaryInstruction.size()==16); if (binaryInstruction.size()!=16){
cerr << "Instruction needs to be exactly 16 bits long, crash in line 105" << endl;
assert(0);
}
for (int i=0; i<16; i++){ for (int i=0; i<16; i++){
temp+=binaryInstr.at(i); temp+=binaryInstruction.at(i);
if(i==3 || i==7 ||i==11 || i==15){ if(i==3 || i==7 || i==11 || i==15){
ans+=convertBinaryToHex(temp); ans+=convertBinaryToHex(temp);
temp="" temp="";
} }
} }
return ans; return ans;
} }
string getRegisterBinary(string reg){
if (reg.size()!=2){
cerr << "Invalid register format, please use form RN, example R0, R3,...; crash in line 120" << endl;
assert(0);
}
if(reg.at(1)=='0'){
return "000";
}else if(reg.at(1)=='1'){
return "001";
}else if(reg.at(1)=='2'){
return "010";
}else if(reg.at(1)=='3'){
return "011";
}else if(reg.at(1)=='4'){
return "100";
}else if(reg.at(1)=='5'){
return "101";
}else if(reg.at(1)=='6'){
return "110";
}else if(reg.at(1)=='7'){
return "111";
}else{
cerr << "Unknown register input (not between 0 and 7), crash in line 140" << endl;
assert(0);
}
}
string getInstructionHex(string instruction){ string getInstructionHex(string instruction){
string opcode = instruction.substr(0, 3);
string rd = instruction.substr(3, 2);
string binary; string binary;
string opcode, rs1, rs2, rd;
if (opcode=="LDA" || opcode=="STA"){ if (opcode=="LDA" || opcode=="STA"){
binary="1"; if (instruction.size()<6){
if(opcode=="LDA"){ cerr << "Instruction format not valid, crash at line 155" << endl;
}else if (opcode=="STA"){
}else {
assert(0); assert(0);
} }
}else{ binary="1";
switch (opcode) { if(opcode=="LDA"){
case "": binary+="0";
// Add code }else if (opcode=="STA"){
break; binary+="1";
}else {
cerr << "Unknown instruction, I think you wanted LDA or STA, crash in line 164" << endl;
assert(0);
} }
binary+=getRegisterBinary(rd);
int lengthOfAddress = instruction.size()-5;
binary+=convertDecimalToBinary(stoi(instruction.substr(5, lengthOfAddress)), 11);
}else{
binary="0";
string rs1, rs2;
if(instruction.size()>=7){
rs1 = instruction.substr(5, 2);
}
if(instruction.size()>=9){
rs2 = instruction.substr(7, 2);
}
if(opcode=="JMP"){
binary+="000000";
rs1="R0";
rs2="R0";
}else if(opcode=="JC1"){
binary+="000100";
}else if(opcode=="JC2"){
binary+="000101";
}else if(opcode=="JC3"){
binary+="000110";
}else if(opcode=="JC4"){
binary+="000111";
rs2="R0";
}else if(opcode=="JC5"){
binary+="001000";
}else if(opcode=="JC6"){
binary+="001001";
}else if(opcode=="JC7"){
binary+="001010";
}else if(opcode=="JC8"){
binary+="001011";
rs2="R0";
}else if(opcode=="AND"){
binary+="001100";
}else if(opcode=="OR"){
binary+="001101";
}else if(opcode=="XOR"){
binary+="001110";
}else if(opcode=="NOT"){
binary+="001111";
rs2="R0";
}else if(opcode=="NND"){
binary+="010000";
}else if(opcode=="NOR"){
binary+="010001";
}else if(opcode=="XNR"){
binary+="010010";
}else if(opcode=="MOV"){
binary+="010011";
rs2="R0";
}else if(opcode=="ADD"){
binary+="010100";
}else if(opcode=="ADC"){
binary+="010101";
}else if(opcode=="ADO"){
binary+="010110";
rs1="R0";
rs2="R0";
}else if(opcode=="SUB"){
binary+"011000";
}else if(opcode=="SBC"){
binary+="011001";
}else if(opcode=="SBO"){
binary+="011010";
rs1="R0";
rs2="R0";
}else if(opcode=="MUL"){
binary+="011100";
}else if(opcode=="MLA"){
binary+="011101";
}else if(opcode=="MLS"){
binary+="011110";
}else if(opcode=="MRT"){
/*
TO BE COMPLETED FOR REGISTERS, ASK AADI
*/
binary+="011111";
}else if(opcode=="LSL"){
binary+="100000";
}else if(opcode=="LSR"){
binary+="100001";
}else if(opcode=="ASR"){
binary+="100011";
}else if(opcode=="ROR"){
binary+="100100";
}else if(opcode=="RRC"){
binary+="100101";
}else if(opcode=="NOP"){
binary+="111110";
rd="R0";
rs1="R0";
rs2="R0";
}else if(opcode=="STP"){
binary+="111111";
rd="R0";
rs1="R0";
rs2="R0";
}else{
assert(0);
}
binary+=getRegisterBinary(rd);
binary+=getRegisterBinary(rs1);
binary+=getRegisterBinary(rs2);
} }
return ans; return convertInstructionToHex(binary);
} }
void generateMIF(vector<string> instructions){ void generateMIF(vector<string> instructions){
@ -108,8 +271,8 @@ void generateMIF(vector<string> instructions){
cout << "CONTENT" << endl; cout << "CONTENT" << endl;
cout << "BEGIN" << endl; cout << "BEGIN" << endl;
cout << "[0..2047]: 0;" << endl; cout << "[0..2047]: 0;" << endl;
for (int i = 0; i <= instruction.size(); i++){ for (int i = 0; i < instructions.size(); i++){
cout << i << " : " << instruction.at(i) << ";" << endl; cout << i << " : " << instructions.at(i) << ";" << endl;
} }
} }
@ -118,7 +281,11 @@ int main(){
string temp; string temp;
vector<string> hexCodes; vector<string> hexCodes;
while(getline(cin, temp)){ while(getline(cin, temp)){
hexCodes.pb(getInstructionHex(temp)); auto it = remove(temp.begin(), temp.end(), ' ');
temp.erase(it, temp.end());
if (temp.size()>=3){
hexCodes.pb(getInstructionHex(temp));
}
} }
generateMIF(hexCodes); generateMIF(hexCodes);
} }