mirror of
https://github.com/supleed2/ELEC40006-P1-CW.git
synced 2024-11-10 02:05:48 +00:00
Completed source code for generating .mif files from opcodes and registers
This commit is contained in:
parent
5d6c9803fc
commit
09dd851499
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue