diff --git a/pa4/Makefile b/pa4/Makefile new file mode 100755 index 0000000..8f90952 --- /dev/null +++ b/pa4/Makefile @@ -0,0 +1,14 @@ +HEADERS = simulator.h + +default: simulator + +simulator.o: simulator.c $(HEADERS) + gcc -c simulator.c -o simulator.o -ggdb -std=c99 + +simulator: simulator.o + gcc simulator.o -o simulator -ggdb -std=c99 + +clean: + -rm -f simulator.o + -rm -f simulator + -rm -f *.out mdump.txt cdump.txt pipe_trace.txt *.aux *.bbl *.blg *.log *.out *.synctex.gz diff --git a/pa4/fibonacci.asm b/pa4/fibonacci.asm new file mode 100644 index 0000000..9f5ba7e --- /dev/null +++ b/pa4/fibonacci.asm @@ -0,0 +1,51 @@ +.text +addi $t9, $zero, 10 +addi $t1, $zero, 0 +addi $t2, $zero, 1 +j fibonacci + +fibonacci: +add $t3, $t2, $t1 +add $t1, $zero, $t2 +add $t2, $zero, $t3 +addi $t5, $t5, 1 +bne $t5, $t9, fibonacci +addi $zero, $zero, 1 + + +.data +2048: .word 10 +2049: .word 10 +2050: .word 20 +2051: .word 30 +2052: .word 40 +2053: .word 50 +2054: .word 60 +2055: .word 70 +2056: .word 80 +2057: .word 90 +2058: .word 100 +2059: .word 3 +2060: .word 3 +2061: .word 3 +2062: .word 3 +2063: .word +2064: .word 11 +2065: .word 10 +2066: .word 20 +2067: .word 30 +2068: .word 40 +2069: .word 50 +2070: .word 60 +2071: .word 70 +2072: .word 80 +2073: .word 90 +2074: .word 100 +2075: .word 3 +2076: .word 3 +2077: .word 3 +2078: .word 3 +2079: .word 3 +2080: .word 5 + + diff --git a/pa4/mipsInstructionMap.h b/pa4/mipsInstructionMap.h new file mode 100644 index 0000000..f55f5bb --- /dev/null +++ b/pa4/mipsInstructionMap.h @@ -0,0 +1,35 @@ +/* + * + * mipsInstructionMap.h + * + * Defines instructions as a hex value for comparison + * + * Modified by Omer Khan + * + */ + +// R-Type Instructions +#define RTYPEOP 0x0 +#define ADD 0x20 +#define SUB 0x21 +#define AND 0x24 +#define OR 0x25 +#define SLL 0x0 +#define SLT 0x2A +#define SRL 0x2 +#define JR 0x8 + +// I-Type Instructions +#define LW 0x23 +#define SW 0x2B +#define ANDI 0xC +#define ORI 0xD +#define LUI 0xF +#define BEQ 0x4 +#define BNE 0x5 +#define SLTI 0xA +#define ADDI 0x8 + +// J-Type Instructions +#define J 0x2 +#define JAL 0x3 diff --git a/pa4/simulator.c b/pa4/simulator.c new file mode 100644 index 0000000..ebd1b7e --- /dev/null +++ b/pa4/simulator.c @@ -0,0 +1,396 @@ +/* + * riscy-uconn simulator.c + */ + +#include +#include +#include +#include "simulator.h" +#include "mipsInstructionMap.h" + +int debug = 0; +int pipe_trace = 1; +int forwarding_enabled = 1; +int cache_enabled = 1; +int cycles_to_access_dmem = 10; + +static FILE *fptr_pt; + +int main(int argc, char *argv[]) { + + FILE *fp; + fp = fopen(argv[1], "r"); + + fptr_pt = fopen("pipe_trace.txt","a"); + + // Call initialize function for registers and instruction/data memory + initialize(fp); + + init_print(); + + // 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; + return 0; +} + +void init_print() { + + operation[ADD] = "ADD"; + operation[SUB] = "SUB"; + operation[AND] = "AND"; + operation[OR] = "OR"; + operation[SLL] = "SLL"; + operation[SLT] = "SLT"; + operation[SRL] = "SRL"; + operation[121] = "JR"; + + // I-Type Instructions + operation[LW] = "LW"; + operation[SW] = "SW"; + operation[ANDI] = "ANDI"; + operation[ORI] = "ORI"; + operation[LUI] = "LUI"; + operation[BEQ] = "BEQ"; + operation[BNE] = "BNE"; + operation[SLTI] = "SLTI"; + operation[ADDI] = "ADDI"; + + // J-Type Instructions + operation[J] = "J"; + operation[JAL] = "JAL"; + +} +// Function to take in instruciton to parse +void process_instructions() { + + int terminate = 0; + while(terminate != 1) { + show_scoreboard(); + write_back(); + execute(); + read_reg(); + issue(); + + cycle++; + /* Termination Condition */ + if (registers[0] != 0) + terminate = 1; + } + show_scoreboard(); + printf("\n TOTAL INSTRUCTIONS EXECUTED: %d", committed_inst); +} + +// Advance PC +void advance_pc(int step) { + pc += step; +} + +void issue() { + +} + +void read_reg() { + +} + +void execute() { + +} + +void write_back() { + +} + + +// Output reigsters +void rdump() +{ + printf("$0 $zero 0x%08x\n", registers[0]); + printf("$1 $at 0x%08x\n", registers[1]); + printf("$2 $v0 0x%08x\n", registers[2]); + printf("$3 $v1 0x%08x\n", registers[3]); + printf("$4 $a0 0x%08x\n", registers[4]); + printf("$5 $a1 0x%08x\n", registers[5]); + printf("$6 $a2 0x%08x\n", registers[6]); + printf("$7 $a3 0x%08x\n", registers[7]); + printf("$8 $t0 0x%08x\n", registers[8]); + printf("$9 $t1 0x%08x\n", registers[9]); + printf("$10 $t2 0x%08x\n", registers[10]); + printf("$11 $t3 0x%08x\n", registers[11]); + printf("$12 $t4 0x%08x\n", registers[12]); + printf("$13 $t5 0x%08x\n", registers[13]); + printf("$14 $t6 0x%08x\n", registers[14]); + printf("$15 $t7 0x%08x\n", registers[15]); + printf("$16 $s0 0x%08x\n", registers[16]); + printf("$17 $s1 0x%08x\n", registers[17]); + printf("$18 $s2 0x%08x\n", registers[18]); + printf("$19 $s3 0x%08x\n", registers[19]); + printf("$20 $s4 0x%08x\n", registers[20]); + printf("$21 $s5 0x%08x\n", registers[21]); + printf("$22 $s6 0x%08x\n", registers[22]); + printf("$23 $s7 0x%08x\n", registers[23]); + printf("$24 $t8 0x%08x\n", registers[24]); + printf("$25 $t9 0x%08x\n", registers[25]); + printf("$26 $k0 0x%08x\n", registers[26]); + printf("$27 $k1 0x%08x\n", registers[27]); + printf("$28 $gp 0x%08x\n", registers[28]); + printf("$29 $sp 0x%08x\n", registers[29]); + printf("$30 $fp 0x%08x\n", registers[30]); + printf("$31 $ra 0x%08x\n", registers[31]); + + printf(" --> pc 0x%08x\n", pc); +} + +void rdump_pt() { + fprintf(fptr_pt, "\n$0 $zero: %d $8 $t0: %d $16 $s0: %d $24 $t8: %d", registers[0], registers[8], registers[16], registers[24]); + fprintf(fptr_pt, "\n$1 $at: %d $9 $t1: %d $17 $s1: %d $25 $t9: %d", registers[1], registers[9], registers[17], registers[25]); + fprintf(fptr_pt, "\n$2 $v0: %d $10 $t2: %d $18 $s2: %d $26 $k0: %d", registers[2], registers[10], registers[18], registers[26]); + fprintf(fptr_pt, "\n$3 $v1: %d $11 $t3: %d $19 $s3: %d $27 $k1: %d", registers[3], registers[11], registers[19], registers[27]); + fprintf(fptr_pt, "\n$4 $a0: %d $12 $t4: %d $20 $s4: %d $28 $gp: %d", registers[4], registers[12], registers[20], registers[28]); + fprintf(fptr_pt, "\n$5 $a1: %d $13 $t5: %d $21 $s5: %d $29 $sp: %d", registers[5], registers[13], registers[21], registers[29]); + fprintf(fptr_pt, "\n$6 $a2: %d $14 $t6: %d $22 $s6: %d $30 $fp: %d", registers[6], registers[14], registers[22], registers[30]); + fprintf(fptr_pt, "\n$7 $a3: %d $15 $t7: %d $23 $s7: %d $31 $ra: %d\n", registers[7], registers[15], registers[23], registers[31]); +} + +// 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]); + //fprintf(fptr,"\n Memory[%d] = %d M[0x%08x]",i,memory[i],i); + } +} + + + + + +void show_scoreboard() { + fprintf(fptr_pt,"--------------------------------------------------------------------------\n"); + fprintf(fptr_pt,"Cycle: %d --- Committed Instructions: %d --- pc: %d\n", cycle, committed_inst, pc); + fprintf(fptr_pt,"Instruction Status\n"); + fprintf(fptr_pt,"Instruction Inst_Num Issue Read-Operands Execution Write-Back\n"); + /* Scan through the scoreboard */ + for (int i = 0; i < MAX_SCB_ENTERIES; i++) { + if (SCOREBOARD[i].busy == 0) continue; + /* Get the assigned unit number */ + int stage = SCOREBOARD[i].stage; + int op = SCOREBOARD[i].operation; + int sub_op = SCOREBOARD[i].sub_operation; + int instruction_number = SCOREBOARD[i].instruction_number; + + if (op != RTYPEOP && sub_op != JR) + fprintf(fptr_pt,"%-13s%-10d%*s\n", operation[op] , instruction_number, spaces[stage],"*"); + else if (op == RTYPEOP && sub_op == JR) { + fprintf(fptr_pt,"%-13s%-10d%*s\n", operation[121] , instruction_number, spaces[stage],"*"); + } + else + fprintf(fptr_pt,"%-13s%-10d%*s\n", operation[sub_op] , instruction_number, spaces[stage],"*"); + + } + fprintf(fptr_pt, "\n"); + + fprintf(fptr_pt,"Num Busy Op dest_reg src_reg1 src_reg2 scb1 scb2 scb1_r scb2_r\n"); + for (int i = 0; i < MAX_SCB_ENTERIES; i++) { + if (SCOREBOARD[i].busy == 0) continue; + if (SCOREBOARD[i].operation != RTYPEOP) { + fprintf(fptr_pt,"%-6d%-7s%-7s%-11d%-11d%-11d%-7d%-7d%-9d%-6d\n", + SCOREBOARD[i].instruction_number, + "Yes", + operation[SCOREBOARD[i].operation], + SCOREBOARD[i].dest_reg, + SCOREBOARD[i].src_reg_1, + SCOREBOARD[i].src_reg_2, + SCOREBOARD[i].scb_1, + SCOREBOARD[i].scb_2, + SCOREBOARD[i].scb_1_ready, + SCOREBOARD[i].scb_2_ready + ); + } + else { + fprintf(fptr_pt,"%-6d%-7s%-7s%-11d%-11d%-11d%-7d%-7d%-9d%-6d\n", + SCOREBOARD[i].instruction_number, + "Yes", + operation[SCOREBOARD[i].sub_operation], + SCOREBOARD[i].dest_reg, + SCOREBOARD[i].src_reg_1, + SCOREBOARD[i].src_reg_2, + SCOREBOARD[i].scb_1, + SCOREBOARD[i].scb_2, + SCOREBOARD[i].scb_1_ready, + SCOREBOARD[i].scb_2_ready + ); + } + + + + } + + fprintf(fptr_pt,"\n"); + fprintf(fptr_pt,"Register Result Status"); + fprintf(fptr_pt, "\n$0 $zero: %d $8 $t0: %d $16 $s0: %d $24 $t8: %d", REGISTERS_RESULT[0], REGISTERS_RESULT[8], REGISTERS_RESULT[16], REGISTERS_RESULT[24]); + fprintf(fptr_pt, "\n$1 $at: %d $9 $t1: %d $17 $s1: %d $25 $t9: %d", REGISTERS_RESULT[1], REGISTERS_RESULT[9], REGISTERS_RESULT[17], REGISTERS_RESULT[25]); + fprintf(fptr_pt, "\n$2 $v0: %d $10 $t2: %d $18 $s2: %d $26 $k0: %d", REGISTERS_RESULT[2], REGISTERS_RESULT[10], REGISTERS_RESULT[18], REGISTERS_RESULT[26]); + fprintf(fptr_pt, "\n$3 $v1: %d $11 $t3: %d $19 $s3: %d $27 $k1: %d", REGISTERS_RESULT[3], REGISTERS_RESULT[11], REGISTERS_RESULT[19], REGISTERS_RESULT[27]); + fprintf(fptr_pt, "\n$4 $a0: %d $12 $t4: %d $20 $s4: %d $28 $gp: %d", REGISTERS_RESULT[4], REGISTERS_RESULT[12], REGISTERS_RESULT[20], REGISTERS_RESULT[28]); + fprintf(fptr_pt, "\n$5 $a1: %d $13 $t5: %d $21 $s5: %d $29 $sp: %d", REGISTERS_RESULT[5], REGISTERS_RESULT[13], REGISTERS_RESULT[21], REGISTERS_RESULT[29]); + fprintf(fptr_pt, "\n$6 $a2: %d $14 $t6: %d $22 $s6: %d $30 $fp: %d", REGISTERS_RESULT[6], REGISTERS_RESULT[14], REGISTERS_RESULT[22], REGISTERS_RESULT[30]); + fprintf(fptr_pt, "\n$7 $a3: %d $15 $t7: %d $23 $s7: %d $31 $ra: %d\n", REGISTERS_RESULT[7], REGISTERS_RESULT[15], REGISTERS_RESULT[23], REGISTERS_RESULT[31]); + + fprintf(fptr_pt,"\nRegister Status"); + rdump_pt(); + fprintf(fptr_pt,"--------------------------------------------------------------------------\n"); + fflush(fptr_pt); +} + +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; + REGISTERS_RESULT[i] = -1; + } + SCOREBOARD = (struct scb_entry *)malloc(MAX_SCB_ENTERIES * sizeof(struct scb_entry)); + + for (int i = 0; i < MAX_SCB_ENTERIES; i++) { + SCOREBOARD[i] = (const struct scb_entry){0}; + } + + + printf("\n Initialized Registers and Scoreboard\n"); + + + /* Omers Stuff Dont touch */ + // 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 'nop' found, move to 0x8000 / 2048 in memory and break + //if (strcmp(line, "00000000000000000000000000000000") == 0) + 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; +} + diff --git a/pa4/simulator.h b/pa4/simulator.h new file mode 100644 index 0000000..e1b3359 --- /dev/null +++ b/pa4/simulator.h @@ -0,0 +1,126 @@ +/* + + * simulator.h + * + * Simulator header file declaring variables and methods + * + */ + +#ifndef SIMULATOR_H_ +#define SIMULATOR_H_ + +// Define MAX_LENGTH for number of registers & instruction length +#define MAX_LENGTH 32 +#define MAX_SCB_ENTERIES 100 + +/* Stages of Pipe Line */ +enum PIPELINE_STAGE {NI, ISS, RD, EX, WB}; +/* Hazards */ //todo +enum HAZARDS {NA, RAW, WAW, WAR, STRUCTURAL}; + +struct Registers +{ + unsigned int inst; + int x; + unsigned int y; + int reg; + int rs; + int rt; + int rd; + int sa; + unsigned short imm; + + int memory_flag; + int addr_mem; + int branch_flag; + int jmp_out_31; + int pc_updated; + + //ALU Inputs/Outputs + int A; + int B; + int C; + int D; + +}; + +// Array of size MAX_LENGTH to hold registers +int registers[MAX_LENGTH]; +int REGISTERS_RESULT[MAX_LENGTH]; + +/* Latencies of each instruction */ +const int OTHER_LATENCY = 5; +const int MEM_LATENCY = 3; +const int BRANCH_LATENCY = 1; + +/* JMP Inst number */ +int inst_num_of_taken_branch = 0; +int instruction_number = 0; + +/* This is a scoreboard entry */ +struct scb_entry { + enum PIPELINE_STAGE stage; + enum HAZARDS hazard; + int busy; + int operation; + int sub_operation; + int dest_reg; + int src_reg_1; + int src_reg_2; + int src_reg_1_data; + int src_reg_2_data; + int scb_1; + int scb_2; + int scb_1_ready; + int scb_2_ready; + int imm; + int shamt; + int result; + int cycles; + int cycles_to_wait; + int instruction_number; + int updated_pc; +}; +struct scb_entry *SCOREBOARD; + + +// PC Register +unsigned int pc = 0; + +// Memory Allocated +int *memory; + +// CLOCK CYCLE +int cycle = 0; +int committed_inst = 0; + + +// Global metadata to support pipelining + +int br_taken = 0; + + + +void initialize(FILE *fp); +void process_instructions(); +int getDec(char *bin); +void isZero(int reg); +void advance_pc(int step); +void rdump(); +void rdump_pt(); +void mdump(); +void inst_dump(char [], unsigned int inst); + +unsigned int fetch(); +void show_scoreboard(); +void init_print(); +void issue(); +void read_reg(); +void execute(); +void write_back(); + + +char spaces[] = {0, 3, 13, 25, 38, 38}; +char *operation[256]; + +#endif /* SIMULATOR_H_ */