#include #include /* #define DEBUG */ #define MAXLINELENGTH 1000 #define MEMSIZE 10000 /* maximum number of memory words */ #define NUMREG 8 #define READ 1 #define WRITE 1 #define ADD 0 #define NAND 1 #define LW 2 #define SW 3 #define BEQ 4 #define JALR 5 #define HALT 6 #define NOOP 7 /* * Control signal values: on or off * Also: definitions of MUX control signals * ALU operations */ #define ON 1 #define OFF 0 #define MUX1aluOperand 0 #define MUX1bus 1 #define MUX2signExtend 0 #define MUX2one 1 #define MUX2bus 2 #define MUX3regA 0 #define MUX3regB 1 #define MUX4regB 0 #define MUX4regD 1 #define ADDop 0 #define SUBop 1 #define NANDop 2 typedef struct _controlSignals{ int PCWrite; int PCWriteCond; int drivePCdata; int drivePCaddr; int latchIR; int driveIRimmediate; int latchALUOperand; int latchALURes; int driveALUdata; int driveALUaddr; int latchCond; int readMem; int writeMem; int readReg; int writeReg; int mux1Control; int mux2Control; int mux3Control; int mux4Control; int ALUOperation; }controlSignals; typedef struct _machineState{ int pc; int instReg; int aluOperand; int aluResult; int condReg; int memory[MEMSIZE]; int regFile[NUMREG]; controlSignals control; }machineState; void printState(memSize, state, stateName) int memSize; machineState state; char stateName[8]; { int i; printf("state: %s\n\n", stateName); printf("\t pc=%d\n",state.pc); printf("\t instReg=%d\n",state.instReg); printf("\t aluOperand=%d\n",state.aluOperand); printf("\t aluResult=%d\n",state.aluResult); printf("\t condReg=%d\n",state.condReg); printf("\t control signals:\n"); if (state.control.PCWrite == ON) {printf("\t \t PCWrite = %d\n", state.control.PCWrite);} if (state.control.PCWriteCond == ON) {printf("\t \t PCWriteCond = %d\n", state.control.PCWriteCond);} if (state.control.drivePCdata == ON) {printf("\t \t drivePCdata = %d\n", state.control.drivePCdata);} if (state.control.drivePCaddr == ON) {printf("\t \t drivePCaddr = %d\n", state.control.drivePCaddr);} if (state.control.latchIR == ON) {printf("\t \t latchIR = %d\n", state.control.latchIR);} if (state.control.driveIRimmediate == ON) {printf("\t \t driveIRimmediate = %d\n", state.control.driveIRimmediate);} if (state.control.latchALUOperand == ON) {printf("\t \t latchALUOperand = %d\n", state.control.latchALUOperand);} if (state.control.latchALURes == ON) {printf("\t \t latchALURes = %d\n", state.control.latchALURes);} if (state.control.driveALUdata == ON) {printf("\t \t driveALUdata = %d\n", state.control.driveALUdata);} if (state.control.driveALUaddr == ON) {printf("\t \t driveALaddr == %d\n", state.control.driveALUaddr);} if (state.control.latchCond == ON) {printf("\t \t latchCond = %d\n", state.control.latchCond);} if (state.control.readMem == ON) {printf("\t \t readMem = %d\n", state.control.readMem);} if (state.control.writeMem == ON) {printf("\t \t writeMem = %d\n", state.control.writeMem);} if (state.control.readReg == ON) {printf("\t \t readReg = %d\n", state.control.readReg);} if (state.control.writeReg == ON) {printf("\t \t writeReg = %d\n", state.control.writeReg);} printf("\t \t mux1Control = %d\n",state.control.mux1Control); printf("\t \t mux2Control = %d\n",state.control.mux2Control); printf("\t \t mux3Control = %d\n",state.control.mux3Control); printf("\t \t mux4Control = %d\n",state.control.mux4Control); printf("\t \t ALUOperation = %d\n",state.control.ALUOperation); printf("\t memory:\n"); for (i=0; icontrol.PCWrite = OFF; statePtr->control.PCWriteCond = OFF; statePtr->control.drivePCdata = OFF; statePtr->control.drivePCaddr = OFF; statePtr->control.latchIR = OFF; statePtr->control.driveIRimmediate = OFF; statePtr->control.latchALUOperand = OFF; statePtr->control.latchALURes = OFF; statePtr->control.driveALUdata = OFF; statePtr->control.driveALUaddr = OFF; statePtr->control.latchCond = OFF; statePtr->control.readMem = OFF; statePtr->control.writeMem = OFF; statePtr->control.readReg = OFF; statePtr->control.writeReg = OFF; statePtr->control.mux1Control = 0; statePtr->control.mux2Control = 0; statePtr->control.mux3Control = 0; statePtr->control.mux4Control = 0; statePtr->control.ALUOperation = 0; } int convertNum(num) int num; { /* * Converts an 8 bit number into a 32-bit number * You should call this routine when you need to perform * sign-extension on the 8-bit offset field. */ if (num & 0x80) { num -= 256; } return(num); } main(argc,argv) int argc; char *argv[]; { FILE *filePtr; int pc, done, instr, i; char line[MAXLINELENGTH]; machineState machine; int opcode, regA, regB, regD, offsetValue; int dataBus, addrBus; int memorySize; int halt; if (argc != 2) { printf("error: usage: %s \n", argv[0]); exit(1); } filePtr = fopen(argv[1], "r"); if (filePtr == NULL) { printf("error: can't open file %s", argv[1]); perror("fopen"); exit(1); } /* read in the entire machine-code file into memory */ pc = 0; done = 0; while (!done){ if (fgets(line, MAXLINELENGTH, filePtr) == NULL){ done = 1; } else { if (sscanf(line, "%d", &instr) != 1) { printf("error in reading address %d\n", pc); exit(1); } machine.memory[pc] = instr; printf("memory[%d]=%d\n", pc, machine.memory[pc]); pc = pc + 1; } } memorySize = pc; pc = 0; halt = 0; for (i=0; i> 14) & 0x7; regA = (machine.instReg >> 11) & 0x7; regB = (machine.instReg >> 8) & 0x7; regD = machine.instReg & 0x7; offsetValue = machine.instReg & 0xff;; /* * Now choose next state. * As you construct the states below, try to share * states among instructions when possible. */ if (opcode == ADD){ goto add1; } if (opcode == NAND){ goto nand1; } if (opcode == LW){ goto lw1; } if (opcode == SW){ goto sw1; } if (opcode == BEQ){ goto beq1; } if (opcode == JALR){ goto jalr1; } if (opcode == HALT){ halt = 1; printf("machine halted.\n"); exit(0); } if (opcode == NOOP){ /* don't need to execute anything */ goto ifetch1; } printf("ERROR: unknown opcode\n"); exit(1); /* * ADD CODE HERE * for the reminaing states of the state diagram. * Follow the example states above: * First, clear control signals. * Then set control signals for the current state. * After calling the printState routine, reflect the changes * to the buses and the machine state. */ } /*while*/ }