-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d878e78
commit 1f458f4
Showing
25 changed files
with
1,380 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
#include <iostream> | ||
#include <bitset> | ||
#include <stdio.h> | ||
#include<stdlib.h> | ||
#include <string> | ||
using namespace std; | ||
|
||
// #define LOG | ||
|
||
#define OPCODE_SZ_BITS 7 | ||
#define REG_SZ_BITS 5 | ||
#define FUNCT3_SZ_BITS 3 | ||
#define FUNCT7_SZ_BITS 7 | ||
#define IMM1_SZ_BITS REG_SZ_BITS | ||
|
||
|
||
#define ALU_ADD 0b0010 | ||
#define ALU_SUB 0b0110 | ||
#define ALU_AND 0b0000 | ||
#define ALU_OR 0b0001 | ||
#define ALU_XOR 0b0100 | ||
#define ALU_SHIFT_RIGHT 0b0101 | ||
|
||
|
||
|
||
class instruction { | ||
public: | ||
bitset<32> instr;//instruction | ||
instruction(bitset<32> fetch); // constructor | ||
|
||
}; | ||
|
||
class CPU { | ||
private: | ||
int dmemory[4096]; //data memory byte addressable in little endian fashion; | ||
unsigned long PC; //pc | ||
unsigned long old_PC; | ||
int32_t registerFile[32]; // Registers x0-x31 | ||
int32_t readData1; | ||
int32_t readData2; | ||
int destReg; | ||
int Imm_val; | ||
int mem_block_output; | ||
int nInstrRType = 0; | ||
|
||
//ALU output signals | ||
int32_t alu_res; | ||
bitset<1> alu_neg; | ||
|
||
class Control { | ||
public: | ||
bitset<1> branch; | ||
bitset<1> MemRead; | ||
bitset<1> Mem2Reg; | ||
bitset<2> ALUOp; | ||
bitset<1> MemWrite; | ||
bitset<1> ALUSrc; | ||
bitset<1> RegWrite; | ||
Control() | ||
{ | ||
branch = 0; | ||
MemRead = 0; | ||
Mem2Reg = 0; | ||
ALUOp = 0; | ||
MemWrite = 0; | ||
ALUSrc = 0; | ||
RegWrite = 0; | ||
} | ||
int ALU_control; | ||
}; | ||
Control ctrl_block; | ||
|
||
public: | ||
int nCycles = 0; | ||
CPU(); | ||
|
||
enum opcode_type | ||
{ | ||
//RTYPE | ||
// ADD = 0b0110011, | ||
// SUB = 0b0110011, | ||
// XOR = 0b0110011, | ||
// SRA = 0b0110011, | ||
RTYPE = 0b0110011, | ||
|
||
//ITYPE | ||
// ANDI = 0b0010011, | ||
// ADDI = 0b0010011, | ||
ITYPE = 0b0010011, | ||
|
||
//LW | ||
_LW = 0b0000011, | ||
|
||
//JALR | ||
_JALR = 0b1100111, | ||
|
||
//STYPE | ||
// SW = 0b0100011, | ||
STYPE = 0b0100011, | ||
|
||
//BTYPE | ||
// BLT = 0b1100011, | ||
BTYPE = 0b1100011, | ||
|
||
//EXIT | ||
_EXIT = 0b0000000 | ||
|
||
}; | ||
|
||
enum opcode | ||
{ | ||
UNKNOWN, | ||
ADD, | ||
SUB, | ||
XOR, | ||
SRA, | ||
|
||
ANDI, | ||
ADDI, | ||
|
||
LW, | ||
|
||
JALR, | ||
|
||
SW, | ||
|
||
BLT, | ||
|
||
EXIT | ||
}; | ||
|
||
unsigned long readPC(); | ||
bitset<32> Fetch(bitset<8> *instmem); | ||
bool Decode(instruction* instr); | ||
bool Execute(int operand1, int operand2, int alu_control); | ||
bool Memory(int alu_output, int reg2); | ||
bool WriteBack(int alu_output, int mem_block_output, int rd); | ||
void update_PC(int Imm_val, bitset<1> alu_neg); | ||
|
||
int Imm_gen(opcode_type type, int imm1, int imm2); | ||
int Imm_gen(opcode_type type, int imm1); | ||
int mux(int in1, int in2, int sel); | ||
int rTypeInstrCount(void); | ||
int32_t read_regFile(int idx); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# CPPFLAGS=-Wall -Wextra -std=c11 -pedantic -ggdb | ||
CPPFLAGS= | ||
TARGET=cpusim | ||
DEFINE= | ||
|
||
all: *.cpp | ||
g++ $(CFLAGS) -o $(TARGET) $^ | ||
|
||
test-r: | ||
./$(TARGET) ../Trace/22instMem-r.txt | ||
test-sw: | ||
./$(TARGET) ../Trace/22instMem-sw.txt | ||
test-all: | ||
./$(TARGET) ../Trace/22instMem-all.txt | ||
test-all-new: | ||
./$(TARGET) ../Trace/22instMem-all.txt | ||
|
||
cpusim-r: *.cpp | ||
g++ $(CFLAGS) -o $(TARGET) $^ && ./$(TARGET) ../Trace/22instMem-r.txt | ||
|
||
cpusim-sw: *.cpp | ||
g++ $(CFLAGS) -o $(TARGET) $^ && ./$(TARGET) ../Trace/22instMem-sw.txt | ||
|
||
cpusim-all: *.cpp | ||
g++ $(CFLAGS) -o $(TARGET) $^ && ./$(TARGET) ../Trace/22instMem-all.txt | ||
cpusim-all-new: *.cpp | ||
g++ $(CFLAGS) -o $(TARGET) $^ && ./$(TARGET) ../Trace/22instMem-all_new.txt | ||
|
||
|
||
clean: | ||
rm $(TARGET) |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
#include "CPU.h" | ||
|
||
#include <iostream> | ||
#include <bitset> | ||
#include <stdio.h> | ||
#include<stdlib.h> | ||
#include <string> | ||
#include<fstream> | ||
#include <sstream> | ||
using namespace std; | ||
|
||
/* | ||
Add all the required standard and developed libraries here | ||
*/ | ||
|
||
/* | ||
Put/Define any helper function/definitions you need here | ||
*/ | ||
int main(int argc, char* argv[]) | ||
{ | ||
/* This is the front end of your project. | ||
You need to first read the instructions that are stored in a file and load them into an instruction memory. | ||
*/ | ||
|
||
/* Each cell should store 1 byte. You can define the memory either dynamically, or define it as a fixed size with size 4KB (i.e., 4096 lines). Each instruction is 32 bits (i.e., 4 lines, saved in little-endian mode). | ||
Each line in the input file is stored as an unsigned char and is 1 byte (each four lines are one instruction). You need to read the file line by line and store it into the memory. You may need a mechanism to convert these values to bits so that you can read opcodes, operands, etc. | ||
*/ | ||
|
||
bitset<8> instMem[4096]; | ||
// int nCycles = 0; | ||
|
||
|
||
if (argc < 2) { | ||
//cout << "No file name entered. Exiting..."; | ||
return -1; | ||
} | ||
|
||
ifstream infile(argv[1]); //open the file | ||
if (!(infile.is_open() && infile.good())) { | ||
cout<<"error opening file\n"; | ||
return 0; | ||
} | ||
string line; | ||
int i = 0; | ||
while (infile) { | ||
infile>>line; | ||
stringstream line2(line); | ||
int x; | ||
line2>>x; | ||
instMem[i] = bitset<8>(x); | ||
i++; | ||
} | ||
int maxPC= i; | ||
|
||
/* Instantiate your CPU object here. CPU class is the main class in this project that defines different components of the processor. | ||
CPU class also has different functions for each stage (e.g., fetching an instruction, decoding, etc.). | ||
*/ | ||
|
||
CPU myCPU; // call the approriate constructor here to initialize the processor... | ||
// make sure to create a variable for PC and resets it to zero (e.g., unsigned int PC = 0); | ||
|
||
/* OPTIONAL: Instantiate your Instruction object here. */ | ||
//Instruction myInst; | ||
bitset<32> curr; | ||
instruction instr = instruction(curr); | ||
bool done = true; | ||
while (done == true) // processor's main loop. Each iteration is equal to one clock cycle. | ||
{ | ||
// nCycles++; | ||
//fetch | ||
curr = myCPU.Fetch(instMem); // fetching the instruction | ||
instr = instruction(curr); | ||
|
||
// decode | ||
done = myCPU.Decode(&instr); | ||
if (done ==false) // break from loop so stats are not mistakenly updated | ||
break; | ||
// the rest should be implemented here ... | ||
// ... | ||
|
||
// sanity check | ||
if (myCPU.readPC() > maxPC) | ||
break; | ||
|
||
#if defined(LOG) | ||
cout << "(" << myCPU.read_regFile(0); | ||
for(int i = 1; i <= 16; i++) | ||
{ | ||
cout << "," << myCPU.read_regFile(i); | ||
} | ||
cout << ")" << endl; | ||
#endif | ||
} | ||
// cout << "number of cycles: " << myCPU.nCycles << endl; | ||
// cout << "number of r-type instructions: " << myCPU.rTypeInstrCount() << endl; | ||
|
||
int a0 = myCPU.read_regFile(10),a1 = myCPU.read_regFile(11); | ||
// print the results (you should replace a0 and a1 with your own variables that point to a0 and a1) | ||
cout << "(" << a0 << "," << a1 << ")" << endl; | ||
|
||
|
||
return 0; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#include<cstdlib> | ||
#include <stdio.h> | ||
#include <math.h> | ||
#include <iostream> | ||
#include <fstream> | ||
#include <string> | ||
#include <vector> | ||
#include <iterator> | ||
#include <sstream> | ||
using namespace std; | ||
void split(const std::string &s, char delim, std::vector<std::string> &elems) { | ||
stringstream ss; | ||
ss.str(s); | ||
string item; | ||
while (std::getline(ss, item, delim)) { | ||
elems.push_back(item); | ||
} | ||
} | ||
// type: r=0, i=1, sw=2; lw=3; beq=4; | ||
// rtype: add=0, sub=1, and=2, or=3; | ||
// itype: addi=0, andi=1, ori=2 | ||
|
||
int main() | ||
{ | ||
|
||
ofstream myfile; | ||
myfile.open ("instMem-test.txt"); | ||
ifstream myAsm; | ||
myAsm.open ("22test.txt"); | ||
string line; | ||
getline(myAsm,line); // getting rid of first line | ||
vector<string> parts; | ||
string inst; | ||
string myByte; | ||
// split(line,'\t',parts); | ||
while(getline(myAsm,line)) | ||
{ | ||
|
||
split(line,'\t',parts); | ||
if( parts.size() >3 ) | ||
{ | ||
inst = parts[3]; | ||
for (int i=0; i<7; i+=2) | ||
{ | ||
myByte.push_back(inst.at(6-i)); | ||
myByte.push_back(inst.at(7-i)); | ||
myfile <<stoi(myByte,nullptr,16) << endl; | ||
myByte.clear(); | ||
} | ||
} | ||
parts.clear(); | ||
|
||
} | ||
|
||
|
||
myfile.close(); | ||
myAsm.close(); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
g++ -o cpusim CPU.cpp cpusim.cpp && ./cpusim ../Trace/22instMem-sw.txt | ||
got stuff rd=1,rs1=0,imm=1 | ||
ADDI instr | ||
alu doing add;got res=1;upd_PC imm=1 alu_neg=0 opcode=6;&res= "0"final PC=4;in wb alu_res=1 mem output0 rd=1mem2reg=0;(0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rd=2,rs1=0,imm=8 | ||
ADDI instr | ||
alu doing add;got res=8;upd_PC imm=8 alu_neg=0 opcode=6;&res= "0"final PC=8;in wb alu_res=8 mem output0 rd=2mem2reg=0;(0,1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rs2=2,rs1=0,imm=4 | ||
operand1 is 0 | ||
operand2 is 4 | ||
alu doing add;got res=4;upd_PC imm=4 alu_neg=0 opcode=9;&res= "0"final PC=12;updated memory(0|0|0|0|8|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|);(0,1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rd=3,rs1=2,rs2=1 | ||
ADD instr | ||
alu doing add;got res=9;upd_PC imm=4 alu_neg=0 opcode=1;&res= "0"final PC=16;in wb alu_res=9 mem output0 rd=3mem2reg=0;(0,1,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rs2=3,rs1=0,imm=8 | ||
operand1 is 0 | ||
operand2 is 8 | ||
alu doing add;got res=8;upd_PC imm=8 alu_neg=0 opcode=9;&res= "0"final PC=20;updated memory(0|0|0|0|8|0|0|0|9|0|0|0|0|0|0|0|0|0|0|0|);(0,1,8,9,0,0,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rd=3,rs1=2,rs2=2 | ||
ADD instr | ||
alu doing add;got res=16;upd_PC imm=8 alu_neg=0 opcode=1;&res= "0"final PC=24;in wb alu_res=16 mem output0 rd=3mem2reg=0;(0,1,8,16,0,0,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rd=4,rs1=0,imm=4 | ||
alu doing add;got res=4;upd_PC imm=4 alu_neg=0 opcode=7;&res= "0"final PC=28;updated memory(0|0|0|0|8|0|0|0|9|0|0|0|0|0|0|0|0|0|0|0|);in wb alu_res=4 mem output8 rd=4mem2reg=1;(0,1,8,16,8,0,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rd=5,rs1=0,imm=8 | ||
alu doing add;got res=8;upd_PC imm=8 alu_neg=0 opcode=7;&res= "0"final PC=32;updated memory(0|0|0|0|8|0|0|0|9|0|0|0|0|0|0|0|0|0|0|0|);in wb alu_res=8 mem output9 rd=5mem2reg=1;(0,1,8,16,8,9,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rd=5,rs1=5,rs2=4 | ||
ADD instr | ||
alu doing add;got res=17;upd_PC imm=8 alu_neg=0 opcode=1;&res= "0"final PC=36;in wb alu_res=17 mem output9 rd=5mem2reg=0;(0,1,8,16,8,17,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rs2=5,rs1=2,imm=4 | ||
operand1 is 8 | ||
operand2 is 4 | ||
alu doing add;got res=12;upd_PC imm=4 alu_neg=0 opcode=9;&res= "0"final PC=40;updated memory(0|0|0|0|8|0|0|0|9|0|0|0|17|0|0|0|0|0|0|0|);(0,1,8,16,8,17,0,0,0,0,0,0,0,0,0,0,0) | ||
got stuff rd=10,rs1=0,imm=8 | ||
alu doing add;got res=8;upd_PC imm=8 alu_neg=0 opcode=7;&res= "0"final PC=44;updated memory(0|0|0|0|8|0|0|0|9|0|0|0|17|0|0|0|0|0|0|0|);in wb alu_res=8 mem output9 rd=10mem2reg=1;(0,1,8,16,8,17,0,0,0,0,9,0,0,0,0,0,0) | ||
got stuff rd=11,rs1=2,imm=4 | ||
alu doing add;got res=12;upd_PC imm=4 alu_neg=0 opcode=7;&res= "0"final PC=48;updated memory(0|0|0|0|8|0|0|0|9|0|0|0|17|0|0|0|0|0|0|0|);in wb alu_res=12 mem output17 rd=11mem2reg=1;(0,1,8,16,8,17,0,0,0,0,9,17,0,0,0,0,0) | ||
EXIT | ||
(9,17) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Oops, something went wrong.