Untitled
unknown
c_cpp
2 years ago
8.0 kB
11
Indexable
#include "mips-small-pipe.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/************************************************************/
int main(int argc, char *argv[]) {
short i;
char line[MAXLINELENGTH];
state_t state;
FILE *filePtr;
if (argc != 2) {
printf("error: usage: %s <machine-code file>\n", argv[0]);
return 1;
}
memset(&state, 0, sizeof(state_t));
state.pc = state.cycles = 0;
state.IFID.instr = state.IDEX.instr = state.EXMEM.instr = state.MEMWB.instr =
state.WBEND.instr = NOPINSTRUCTION; /* nop */
/* read machine-code file into instruction/data memory (starting at address 0)
*/
filePtr = fopen(argv[1], "r");
if (filePtr == NULL) {
printf("error: can't open file %s\n", argv[1]);
perror("fopen");
exit(1);
}
for (state.numMemory = 0; fgets(line, MAXLINELENGTH, filePtr) != NULL;
state.numMemory++) {
if (sscanf(line, "%x", &state.dataMem[state.numMemory]) != 1) {
printf("error in reading address %d\n", state.numMemory);
exit(1);
}
state.instrMem[state.numMemory] = state.dataMem[state.numMemory];
printf("memory[%d]=%x\n", state.numMemory, state.dataMem[state.numMemory]);
}
printf("%d memory words\n", state.numMemory);
printf("\tinstruction memory:\n");
for (i = 0; i < state.numMemory; i++) {
printf("\t\tinstrMem[ %d ] = ", i);
printInstruction(state.instrMem[i]);
}
run(&state);
return 0;
}
/************************************************************/
/************************************************************/
void run(Pstate state) {
state_t new;
memset(&new, 0, sizeof(state_t));
while (1) {
printState(state);
/* copy everything so all we have to do is make changes.
(this is primarily for the memory and reg arrays) */
memcpy(&new, state, sizeof(state_t));
new.cycles++;
/* --------------------- IF stage --------------------- */
new.IFID.instr = state->instrMem[state->cycles];
new.pc = state -> pc+4;
/* --------------------- ID stage --------------------- */
new.IDEX.pcPlus1 = state->IFID.pcPlus1;
new.IDEX.instr = state->IFID.instr;
/* --------------------- EX stage --------------------- */
new.EXMEM.instr = state->IDEX.instr;
/* --------------------- MEM stage --------------------- */
new.MEMWB.instr = state->EXMEM.instr;
/* --------------------- WB stage --------------------- */
new.WBEND.instr = state->MEMWB.instr;
/* --------------------- end stage --------------------- */
if (opcode(state->MEMWB.instr) == HALT_OP) {
printf("machine halted\n");
printf("total of %d cycles executed\n", state->cycles);
exit(1);
}
/* transfer new state into current state */
memcpy(state, &new, sizeof(state_t));
}
}
/************************************************************/
/************************************************************/
int opcode(int instruction) { return (instruction >> OP_SHIFT) & OP_MASK; }
/************************************************************/
/************************************************************/
int func(int instruction) { return (instruction & FUNC_MASK); }
/************************************************************/
/************************************************************/
int field_r1(int instruction) { return (instruction >> R1_SHIFT) & REG_MASK; }
/************************************************************/
/************************************************************/
int field_r2(int instruction) { return (instruction >> R2_SHIFT) & REG_MASK; }
/************************************************************/
/************************************************************/
int field_r3(int instruction) { return (instruction >> R3_SHIFT) & REG_MASK; }
/************************************************************/
/************************************************************/
int field_imm(int instruction) { return (instruction & IMMEDIATE_MASK); }
/************************************************************/
/************************************************************/
int offset(int instruction) {
/* only used for lw, sw, beqz */
return convertNum(field_imm(instruction));
}
/************************************************************/
/************************************************************/
int convertNum(int num) {
/* convert a 16 bit number into a 32-bit Sun number */
if (num & 0x8000) {
num -= 65536;
}
return (num);
}
/************************************************************/
/************************************************************/
void printState(Pstate state) {
short i;
printf("@@@\nstate before cycle %d starts\n", state->cycles);
printf("\tpc %d\n", state->pc);
printf("\tdata memory:\n");
for (i = 0; i < state->numMemory; i++) {
printf("\t\tdataMem[ %d ] %d\n", i, state->dataMem[i]);
}
printf("\tregisters:\n");
for (i = 0; i < NUMREGS; i++) {
printf("\t\treg[ %d ] %d\n", i, state->reg[i]);
}
printf("\tIFID:\n");
printf("\t\tinstruction ");
printInstruction(state->IFID.instr);
printf("\t\tpcPlus1 %d\n", state->IFID.pcPlus1);
printf("\tIDEX:\n");
printf("\t\tinstruction ");
printInstruction(state->IDEX.instr);
printf("\t\tpcPlus1 %d\n", state->IDEX.pcPlus1);
printf("\t\treadRegA %d\n", state->IDEX.readRegA);
printf("\t\treadRegB %d\n", state->IDEX.readRegB);
printf("\t\toffset %d\n", state->IDEX.offset);
printf("\tEXMEM:\n");
printf("\t\tinstruction ");
printInstruction(state->EXMEM.instr);
printf("\t\taluResult %d\n", state->EXMEM.aluResult);
printf("\t\treadRegB %d\n", state->EXMEM.readRegB);
printf("\tMEMWB:\n");
printf("\t\tinstruction ");
printInstruction(state->MEMWB.instr);
printf("\t\twriteData %d\n", state->MEMWB.writeData);
printf("\tWBEND:\n");
printf("\t\tinstruction ");
printInstruction(state->WBEND.instr);
printf("\t\twriteData %d\n", state->WBEND.writeData);
}
/************************************************************/
/************************************************************/
void printInstruction(int instr) {
if (opcode(instr) == REG_REG_OP) {
if (func(instr) == ADD_FUNC) {
print_rtype(instr, "add");
} else if (func(instr) == SLL_FUNC) {
print_rtype(instr, "sll");
} else if (func(instr) == SRL_FUNC) {
print_rtype(instr, "srl");
} else if (func(instr) == SUB_FUNC) {
print_rtype(instr, "sub");
} else if (func(instr) == AND_FUNC) {
print_rtype(instr, "and");
} else if (func(instr) == OR_FUNC) {
print_rtype(instr, "or");
} else {
printf("data: %d\n", instr);
}
} else if (opcode(instr) == ADDI_OP) {
print_itype(instr, "addi");
} else if (opcode(instr) == LW_OP) {
print_itype(instr, "lw");
} else if (opcode(instr) == SW_OP) {
print_itype(instr, "sw");
} else if (opcode(instr) == BEQZ_OP) {
print_itype(instr, "beqz");
} else if (opcode(instr) == HALT_OP) {
printf("halt\n");
} else {
printf("data: %d\n", instr);
}
}
/************************************************************/
/************************************************************/
void print_rtype(int instr, const char *name) {
printf("%s %d %d %d\n", name, field_r3(instr), field_r1(instr),
field_r2(instr));
}
/************************************************************/
/************************************************************/
void print_itype(int instr, const char *name) {
printf("%s %d %d %d\n", name, field_r2(instr), field_r1(instr),
offset(instr));
}
/************************************************************/
Editor is loading...