mirror of
https://github.com/supleed2/ELEC40006-P1-CW.git
synced 2024-12-22 21:45:49 +00:00
Merge branch 'master' of https://github.com/supleed2/CPUProject
This commit is contained in:
commit
12bd671c00
|
@ -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 <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -14,17 +33,6 @@ using namespace std;
|
|||
const unsigned int RAM_SIZE = 2048;
|
||||
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){
|
||||
if(binary4=="0000"){
|
||||
return "0";
|
||||
|
@ -59,45 +67,200 @@ string convertBinaryToHex(string binary4){
|
|||
}else if(binary4=="1111"){
|
||||
return "F";
|
||||
}else{
|
||||
cerr << "Invalide binary quartet, cannot convert to HEX (line 78 in .cpp file)" << endl;
|
||||
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 ans="";
|
||||
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++){
|
||||
temp+=binaryInstr.at(i);
|
||||
if(i==3 || i==7 ||i==11 || i==15){
|
||||
temp+=binaryInstruction.at(i);
|
||||
if(i==3 || i==7 || i==11 || i==15){
|
||||
ans+=convertBinaryToHex(temp);
|
||||
temp=""
|
||||
temp="";
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
string getInstructionHex(string instruction){
|
||||
string binary;
|
||||
string opcode, rs1, rs2, rd;
|
||||
|
||||
if (opcode=="LDA" || opcode=="STA"){
|
||||
binary="1";
|
||||
if(opcode=="LDA"){
|
||||
|
||||
}else if (opcode=="STA"){
|
||||
|
||||
}else {
|
||||
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{
|
||||
switch (opcode) {
|
||||
case "":
|
||||
// Add code
|
||||
break;
|
||||
cerr << "Unknown register input (not between 0 and 7), crash in line 140" << endl;
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
string getInstructionHex(string instruction){
|
||||
string opcode = instruction.substr(0, 3);
|
||||
string rd = instruction.substr(3, 2);
|
||||
string binary;
|
||||
|
||||
if (opcode=="LDA" || opcode=="STA"){
|
||||
if (instruction.size()<6){
|
||||
cerr << "Instruction format not valid, crash at line 155" << endl;
|
||||
assert(0);
|
||||
}
|
||||
return ans;
|
||||
binary="1";
|
||||
if(opcode=="LDA"){
|
||||
binary+="0";
|
||||
}else if (opcode=="STA"){
|
||||
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 convertInstructionToHex(binary);
|
||||
}
|
||||
|
||||
void generateMIF(vector<string> instructions){
|
||||
|
@ -108,8 +271,8 @@ void generateMIF(vector<string> instructions){
|
|||
cout << "CONTENT" << endl;
|
||||
cout << "BEGIN" << endl;
|
||||
cout << "[0..2047]: 0;" << endl;
|
||||
for (int i = 0; i <= instruction.size(); i++){
|
||||
cout << i << " : " << instruction.at(i) << ";" << endl;
|
||||
for (int i = 0; i < instructions.size(); i++){
|
||||
cout << i << " : " << instructions.at(i) << ";" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,7 +281,11 @@ int main(){
|
|||
string temp;
|
||||
vector<string> hexCodes;
|
||||
while(getline(cin, temp)){
|
||||
auto it = remove(temp.begin(), temp.end(), ' ');
|
||||
temp.erase(it, temp.end());
|
||||
if (temp.size()>=3){
|
||||
hexCodes.pb(getInstructionHex(temp));
|
||||
}
|
||||
}
|
||||
generateMIF(hexCodes);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue