Untitled

mail@pastecode.io avatar
unknown
python
a year ago
8.1 kB
6
Indexable
Never
/*###################################################################################
Note: Please don’t upload the assignments, template file/solution and lab. manual on GitHub or others public repository. 
It violates the BITS’s Intellectual Property Rights (IPR).
************************************************************************************/

#include <stdio.h>
#include <cstdint>

//Opcode of MIPS's instructions
#define R_OP 0
#define ADD_Func 32	
#define ADDI_OP 0b0001000// 8
#define LW_OP 35
#define SW_OP 43
#define BNE_OP 5
#define STP_OP 63 //Not a MIPS instruction 

uint32_t PC; //Program counter

int32_t JAddr;
uint8_t Shamt; // for shifting
uint8_t Funct, ALUOP;
uint8_t RS, RT, RD;
int16_t Immediate;

bool ZeroFlag; //

int32_t RegFile[32];

uint8_t Imem[256], Dmem[256]; //2^8 locations, byte addressable Instruction and Data memory

uint8_t  run = 1; //

void readRegfile(uint8_t in_reg_1,  uint8_t in_reg_2, int32_t *out_reg_1, int32_t *out_reg_2) {

	//First Register
	*out_reg_1 = RegFile[in_reg_1];
	//Second Register
	*out_reg_2 = RegFile[in_reg_2];
}
void writeRegfile(uint8_t in_reg, bool RegWrite, int32_t *out_reg) {
	    
	if (RegWrite==true){
		if (in_reg == 0 )
	    	printf("Don't try to modify R0\n");
		else
			RegFile[in_reg] = *out_reg;}
	
}
int ALU(int in1, int in2) {
	int result;
	switch (ALUOP) {

		//used for LW, SW, ADDI 
		case 0:		
			result = in1 + in2;
			
			break;
		//used for BNE //
		case 1: result = in1 - in2;
		    
			break;
		//for rest of the instruction types
		case 2:
			switch(Funct) {
			
			case ADD_Func:  result = in1 + in2;
			              
					break;					
			
			}
		break;
	}
	
	if (result == 0)
		ZeroFlag = true;
	else
	    ZeroFlag = false;

	return result;
}
uint32_t readIMM(uint32_t addr) {
	//Big-endian format - lower byte - higher address
	uint8_t byte0, byte1, byte2, byte3;
	uint32_t instr;
	
	byte3 = Imem[addr+0];		
	byte2 = Imem[addr+1];
	byte1 = Imem[addr+2];
	byte0 = Imem[addr+3];	
	
	instr = (byte3 << 24) + (byte2 << 16) + (byte1 << 8) + byte0;
	
	return instr;
}
int readDMM(int addr, bool MemRead) {
	//Big-endian format  - lower byte - higher address
	uint8_t byte0, byte1, byte2, byte3;
	int data;
	if (MemRead) {		
		
		byte3 = Dmem[addr+0];
		byte2 = Dmem[addr+1];
		byte1 = Dmem[addr+2];
		byte0 = Dmem[addr+3];		
		data = (byte3 << 24) + (byte2 << 16) + (byte1 << 8) + byte0;	
	}
	else
		printf("Error from Data memory's read module\n");
	return data;
}
void writeDMM(uint32_t addr, int data, bool MemWrite) {
	//Big-endian format  - lower byte - higher address
	uint8_t byte0, byte1, byte2, byte3;
	
	if (MemWrite) {
		
		byte3 = data >> 24;
		byte2 = (data & 0b00000000111111110000000000000000) >> 16;
		byte1 = (data & 0b00000000000000001111111100000000) >> 8;
		byte0 = (data & 0b00000000000000000000000011111111);
		
		Dmem[addr+0] = byte3;
		Dmem[addr+1] = byte2;
		Dmem[addr+2] = byte1;
		Dmem[addr+3] = byte0;	
		
	}
	else
		printf("Error from Data memory's write module\n");
		
}
uint32_t incrementPC(uint32_t pc){
	return pc + 4;
}
int32_t addBranchAddr(int32_t pc, int32_t branchAddr){
	return pc + branchAddr;
}
int32_t signExtn(int16_t offset) {
	int32_t temp;
	temp = offset;
	return temp;	
}
uint32_t leftShift2_16(int16_t offset) {
	int32_t temp;
	temp = offset;
	temp = temp << 2;
	return temp;
}
uint32_t leftShift2_25(int32_t offset) {
	int32_t temp;
	temp = offset << 2;
	return temp;
}
uint8_t fetchDecodeFSM(void) {
	uint8_t Opcode; // Other Global variable can be used.
	//Write your code here, without declareending extra variables
	Opcode = (readIMM(PC) >> 26) & 0x3F;
    RS = (readIMM(PC) >> 21) & 0x1F; 
    RT = (readIMM(PC) >> 16) & 0x1F; 
    RD = (readIMM(PC) >> 11) & 0x1F;
	Shamt = (readIMM(PC) >>6 ) & 0x1F;
	Funct = (readIMM(PC)) & 0x3F;
	Immediate = readIMM(PC) & 0xFFFF;

	PC = incrementPC(PC);

	return Opcode;
}
void lwFSM(void) {
	
	int32_t out_reg1, out_reg2, out_reg;
	//Write your code here, without declareending extra variables
	readRegfile(RS,RT,&out_reg1,&out_reg2);
	out_reg = readDMM(ALU(out_reg1, signExtn(Immediate)),true);
	writeRegfile(RT, true, &out_reg);
}

void swFSM(void) {
		
	int32_t out_reg1, out_reg2, out_reg;
	//Write your code here, without declareending extra variables
	readRegfile(RS,RT,&out_reg1,&out_reg2);
	writeDMM(ALU(out_reg1, signExtn(Immediate)), out_reg2,true);
}
void addFSM(void) {	
	
	int32_t out_reg1, out_reg2, out_reg;
	//Write your code here, without declareending extra variables
	readRegfile(RS,RT,&out_reg1,&out_reg2);
	out_reg = ALU(out_reg1,out_reg2);
	writeRegfile(RD,true,&out_reg);
	
	
}
void addiFSM(void) {
	
	int32_t out_reg1, out_reg2, out_reg;
	//Write your code here, without declareending extra variables
	readRegfile(RS,RT,&out_reg1,&out_reg2);
	out_reg = (ALU(out_reg1, signExtn(Immediate)));
	writeRegfile(RT,true,&out_reg);
}
void bneFSM(void) {
		
	int32_t out_reg1, out_reg2, out_reg;
	//Write your code here, without declareending extra variables
	readRegfile(RS,RT,&out_reg1,&out_reg2);
	out_reg = ALU(out_reg1,out_reg2);
	if(!ZeroFlag){
		PC = addBranchAddr(PC, leftShift2_25(signExtn(Immediate)));
	}
	
}

void stpFSM(void) {
	run=0;
}


void load_program(void);
int main(void) {
	
	RegFile[0] = 0;
	load_program();
	PC = 0;
	while (run) {
		uint8_t opcode = fetchDecodeFSM();
		switch (opcode)
		{

			case R_OP:  
			    ALUOP = 2;
				switch (Funct) {
					case ADD_Func: addFSM();
						break;
									
				}	

				break;
			case ADDI_OP: ALUOP = 0; addiFSM(); break;
			case LW_OP:   ALUOP = 0; lwFSM(); break;
			case SW_OP:   ALUOP = 0; swFSM(); break;			
			case BNE_OP:  ALUOP = 1; bneFSM(); break;
			case STP_OP: stpFSM(); break;		
		}
	}
	printf("The Fibonacci numbers are:\n");
	for (int i = 0; i < 7; i++) {
		uint8_t byte0, byte1, byte2, byte3;
		int data;
		
		data = readDMM(252-(4*i), true);
		printf("%d, ", data);
	}
		
}
void load_program(void) {

	
	//Big-endian format lower-order addresses are used for the most significant byte
	Dmem[255] = 0b00000001;
	Dmem[254] = 0b00000000;
	Dmem[253] = 0b00000000;
	Dmem[252] = 0b00000000;

	Dmem[251] = 0b00000001;
	Dmem[250] = 0b00000000;
	Dmem[249] = 0b00000000;
	Dmem[248] = 0b00000000;	
	
	//Instructions
	
	// Code for generating the first 7 Fibonacci numbers.

	//ADDI R1, R0, 252 - ---- R1 <- R0 + 252
	Imem[0] = 0b00100000; 
	Imem[1] = 0b00000001;
	Imem[2] = 0b00000000;
	Imem[3] = 0b11111100;
	//ADDI R2, R0, 2 - ---- R2 <- R0 + 2 // counter
	Imem[4] = 0b00100000; 
	Imem[5] = 0b00000010;
	Imem[6] = 0b00000000;
	Imem[7] = 0b00000010;
	//ADDI R7, R0, 7 - ---- R7 <- R0 + 7 // Max val // doubt
	Imem[8] = 0b00100000;
	Imem[9] = 0b00000111;
	Imem[10] = 0b00000000;
	Imem[11] = 0b00000111;
	//LW R3, R1, 0 - ---- R3 <- Dmem[R1 + 0]
	Imem[12] = 0b10001100; 
	Imem[13] = 0b00100011;
	Imem[14] = 0b00000000;
	Imem[15] = 0b00000000; 
	//ADDI R1, R1, -4 - ---- R1 <- R1 - 4   //R1 - 248
	Imem[16] = 0b00100000; 
	Imem[17] = 0b00100001;
	Imem[18] = 0b11111111;
	Imem[19] = 0b11111100;
	//LW R4, R1, 0 - ---- R4 <- Dmem[R1 + 0]
	Imem[20] = 0b10001100; 
	Imem[21] = 0b00100100;
	Imem[22] = 0b00000000;
	Imem[23] = 0b00000000;
	//ADD R5, R3, R4 - ---- R5 <- R3 + R4
	Imem[24] = 0b00000000;
	Imem[25] = 0b01100100;
	Imem[26] = 0b00101000;
	Imem[27] = 0b00100000;
	//SW R5, R1, -4 - ---- Dmem[R1 - 4] <- R5 // 248-4 = 244
	Imem[28] = 0b10101100; 
	Imem[29] = 0b00100101;
	Imem[30] = 0b11111111;
	Imem[31] = 0b11111100;
	//ADDI R2, R2, 1 - ---- R2 <- R2 + 1   //Counter
	Imem[32] = 0b00100000; 
	Imem[33] = 0b01000010;
	Imem[34] = 0b00000000;
	Imem[35] = 0b00000001;
	//BNE R7, R2, -7(instructions)
	Imem[36] = 0b00010100; 
	Imem[37] = 0b01000111;
	Imem[38] = 0b11111111;
	Imem[39] = 0b11111001;
	 //STP
	Imem[40] = 0b11111100;
	Imem[41] = 0b00000000;
	Imem[42] = 0b00000000;
	Imem[43] = 0b00000000;	
}