Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
cse4302/pa0/simulator.c
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
289 lines (233 sloc)
6.65 KB
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
/* | |
* riscy-uconn simulator.c | |
*/ | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include "simulator.h" | |
#include "instruction_map.h" | |
int debug = 0; | |
int main(int argc, char *argv[]) { | |
if (argc != 2) { | |
printf("Incorrect number of arguments\n"); | |
exit(1); | |
} | |
else { | |
// Open Input file | |
FILE *fp; | |
fp = fopen(argv[1], "r"); | |
// Call initialize function for registers and instruction/data memory | |
initialize(fp); | |
// Process one instruction at a time | |
process_instructions(); | |
printf("\n Printing Output Registers \n"); | |
// Output registers | |
rdump(); | |
// Output Memory | |
mdump(); | |
// Dealloc .data | |
free(memory); | |
memory = NULL; | |
// Close File | |
fclose (fp); | |
return 0; | |
} | |
} | |
// Function to take in instruciton to parse | |
void process_instructions() { | |
int terminate = 0; | |
// Cycle PC | |
int instruction_counter = 0; | |
while(terminate != 1) | |
{ | |
// set terminate flag when SLL $0, $0, 0 (aka NOOP) is executed | |
if (memory[pc/4] == nop) | |
terminate = 1; | |
//Fetch Instruction | |
unsigned int instruction_fetch; | |
instruction_fetch = fetch(); | |
if(debug==1) | |
printf("\n IMEM ADDR:%d instruction 0x%08x", pc/4, instruction_fetch); | |
instruction_counter++; | |
// Decode Instruction | |
struct Registers decode_out; | |
decode_out = decode(instruction_fetch); | |
// Execute Instruction | |
struct Registers alu_out; | |
alu_out = execute(decode_out); | |
// Memory Stage | |
struct Registers mem_out; | |
mem_out = memory_stage(alu_out); | |
// Write Back Stage | |
write_back_stage(mem_out); | |
}//while pc loop | |
printf("\n TOTAL INSTRUCTIONS EXECUTED: %d", instruction_counter); | |
} //process_instruction | |
// Advance PC | |
void advance_pc(int step) { | |
pc += step; | |
} | |
unsigned int fetch() { | |
unsigned int inst = 0; | |
return inst = memory[pc/4]; | |
} | |
struct Registers decode(unsigned int instruction_fetch) { | |
struct Registers reg_temp; | |
// your code for decode phase goes here. | |
return reg_temp; | |
} | |
struct Registers execute(struct Registers decode_out) | |
{ | |
return decode_out; | |
} | |
struct Registers memory_stage(struct Registers alu_out) | |
{ | |
return alu_out; | |
} | |
void write_back_stage(struct Registers mem_out) | |
{ | |
} // WB Done | |
// Output reigsters | |
void rdump() | |
{ | |
printf("x0 zero 0x%08x\n", registers[0]); | |
printf("x1 ra 0x%08x\n", registers[1]); | |
printf("x2 sp 0x%08x\n", registers[2]); | |
printf("x3 gp 0x%08x\n", registers[3]); | |
printf("x4 tp 0x%08x\n", registers[4]); | |
printf("x5 t0 0x%08x\n", registers[5]); | |
printf("x6 t1 0x%08x\n", registers[6]); | |
printf("x7 t2 0x%08x\n", registers[7]); | |
printf("x8 s0 0x%08x\n", registers[8]); | |
printf("x9 s1 0x%08x\n", registers[9]); | |
printf("x10 a0 0x%08x\n", registers[10]); | |
printf("x11 a1 0x%08x\n", registers[11]); | |
printf("x12 a2 0x%08x\n", registers[12]); | |
printf("x13 a3 0x%08x\n", registers[13]); | |
printf("x14 a4 0x%08x\n", registers[14]); | |
printf("x15 a5 0x%08x\n", registers[15]); | |
printf("x16 a6 0x%08x\n", registers[16]); | |
printf("x17 a7 0x%08x\n", registers[17]); | |
printf("x18 s2 0x%08x\n", registers[18]); | |
printf("x19 s3 0x%08x\n", registers[19]); | |
printf("x20 s4 0x%08x\n", registers[20]); | |
printf("x21 s5 0x%08x\n", registers[21]); | |
printf("x22 s6 0x%08x\n", registers[22]); | |
printf("x23 s7 0x%08x\n", registers[23]); | |
printf("x24 s8 0x%08x\n", registers[24]); | |
printf("x25 s9 0x%08x\n", registers[25]); | |
printf("x26 s10 0x%08x\n", registers[26]); | |
printf("x27 s11 0x%08x\n", registers[27]); | |
printf("x28 t3 0x%08x\n", registers[28]); | |
printf("x29 t4 0x%08x\n", registers[29]); | |
printf("x30 t5 0x%08x\n", registers[30]); | |
printf("x31 t6 0x%08x\n", registers[31]); | |
printf(" --> pc 0x%08x\n", pc); | |
} | |
// Output Memory | |
void mdump() | |
{ | |
FILE *fptr; | |
fptr = fopen("mdump.txt","w"); | |
int i = 0; | |
for(i=0;i<16384;i++) | |
{ | |
fprintf(fptr,"\n Memory[%d] = %d",i,memory[i]); | |
} | |
} | |
void initialize(FILE *fp) | |
{ | |
if (fp == NULL) | |
{ | |
printf("Error opening input file.\n"); | |
exit(1); | |
} | |
// Initialize registers values' to 0x0 | |
for (int i = 0; i < 32; i++) | |
registers[i] = 0x0; | |
printf("\n Initialized Registers \n"); | |
// Malloc memory | |
memory = (int *)malloc(16384 * sizeof(int)); | |
if (memory == NULL) | |
{ | |
printf("Not enough memory. Aborting..\n"); | |
exit(1); | |
} | |
// Initialize 'memory' array to -1 | |
for (int i = 0; i < 16384; i++) | |
{ | |
memory[i] = -1; | |
} | |
printf("\n Initialized Memory \n"); | |
// Initialize variables for parsing | |
char line[MAX_LENGTH+2]; | |
char *p; | |
int i = 0, line_num = 0; | |
//int line_num = 0, i = 0, data_line = 0; | |
// Copy .text section to memory, breaks at nop | |
while (fgets(line, MAX_LENGTH+2, fp) != NULL) | |
{ | |
line_num++; | |
// Remove '\n' from 'line' | |
p = strchr(line, '\n'); | |
if (p != NULL) | |
*p = '\0'; | |
memory[i] = getDec(line); | |
//printf("\n %d",memory[i]); | |
if (strcmp(line, "11111111111111111111111111111111") == 0) | |
{ | |
memory[i] = 0; | |
i = 0x800; | |
break; | |
} | |
else | |
i++; | |
} | |
int j = 2048; //Data Memory Starts at 2048 | |
for(j=i;j<16384;j++) | |
{ | |
memory[j] = 2; | |
//printf("\n %d",memory[i]); | |
} | |
printf("\n Instructions Read, Memory Offset: %d\n", line_num); | |
// Seek fp to first instruction in .data | |
char data[MAX_LENGTH+2]; | |
int bytes = 33 * line_num; | |
fseek(fp, bytes, SEEK_SET); | |
// Copy .data section to memory | |
while (fgets(line, MAX_LENGTH+2, fp) != NULL) | |
{ | |
// Remove '\n' from 'line' | |
p = strchr(line, '\n'); | |
if (p != NULL) | |
*p = '\0'; | |
memory[i] = getDec(line); | |
printf("\n Data: %d %d",i,memory[i]); | |
i++; | |
} | |
printf("\n Data put in Memory \n"); | |
} | |
// Convert a binary string to a decimal value | |
int getDec(char *bin) | |
{ | |
int b, k, m, n; | |
int len, sum = 0; | |
// Length - 1 to accomodate for null terminator | |
len = strlen(bin) - 1; | |
// Iterate the string | |
for(k = 0; k <= len; k++) | |
{ | |
// Convert char to numeric value | |
n = (bin[k] - '0'); | |
// Check the character is binary | |
if ((n > 1) || (n < 0)) | |
{ | |
return 0; | |
} | |
for(b = 1, m = len; m > k; m--) | |
b *= 2; | |
// sum it up | |
sum = sum + n * b; | |
} | |
return sum; | |
} |