/** * University of Illinois/NCSA * Open Source License * * Copyright (c) 2007-2008,The Board of Trustees of the University of * Illinois. All rights reserved. * * Copyright (c) 2009 Sam King * * Developed by: * * Professor Sam King in the Department of Computer Science * The University of Illinois at Urbana-Champaign * http://www.cs.uiuc.edu/homes/kingst/Research.html * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated * documentation files (the "Software"), to deal with the * Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit * persons to whom the Software is furnished to do so, subject * to the following conditions: * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimers. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the * following disclaimers in the documentation and/or other * materials provided with the distribution. * * Neither the names of Sam King, the University of Illinois, * nor the names of its contributors may be used to endorse * or promote products derived from this Software without * specific prior written permission. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS WITH THE SOFTWARE. */ #include <stdlib.h> #include <assert.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <signal.h> #include <time.h> #include <string.h> #include <iostream> #include <fstream> #include <string> #include <sstream> using namespace std; #define RAM_SIZE 0x20000 #define NUM_REGS 32 #define OP_FORMAT_1 0x1 #define OP_FORMAT_2 0x0 #define OP_FORMAT_3_ALU 0x2 #define OP_FORMAT_3_MEM 0x3 #define OP2_BRANCH 0x2 #define OP2_SETHI 0x4 #define OP3_ADD 0x0 #define OP3_SUB 0x4 #define OP3_SUBCC 0x14 #define OP3_JMPL 0x38 #define OP3_LD 0x0 #define OP3_ST 0x4 #define COND_BNE 0x9 #define COND_B 0x8 #define COND_BE 0x1 int PRINT_INST = 0; #define COUT(x) do { if(PRINT_INST) { x; } } while(0) typedef uint32_t u32; typedef int32_t i32; struct CPU { u32 regs[NUM_REGS]; u32 pc; u32 branch_pc; bool icc_z; bool icc_n; }; struct control_signals { u32 op; u32 rd; u32 cond; u32 op2; u32 op3; u32 rs1; u32 i; u32 asi; i32 simm; u32 imm; u32 disp22; u32 disp30; u32 rs2; u32 raw; }; static uint8_t *ram = NULL; static bool userQuit = false; static time_t startTime; void ctrlC(int /*signo*/) { userQuit = true; } u32 fetch(struct CPU */*cpu*/) { u32 opcode = 0; // XXX FILL THIS IN return opcode; } i32 sign_extend_22(u32 disp22) { i32 ret; ret = disp22; assert((disp22 & 0xffc00000) == 0); if((disp22 & 0x200000) != 0) { ret |= 0xffc00000; } return ret; } i32 sign_extend_13(u32 imm) { i32 ret; ret = imm; assert((imm & 0xffffe000) == 0); if((imm & 0x0100) != 0) { ret |= 0xffffe000; } return ret; } void decode_control_signals(u32 opcode, struct control_signals *control) { control->raw = opcode; control->op = (opcode >> 30) & 0x3; control->rd = (opcode >> 25) & 0x1f; control->op2 = (opcode >> 22) & 0x7; control->op3 = (opcode >> 19) & 0x3f; control->rs1 = (opcode >> 14) & 0x1f; control->i = (opcode >> 13) & 0x1; control->asi = (opcode >> 5) & 0xff; control->simm = sign_extend_13(opcode & 0x1fff); control->imm = opcode & 0x3fffff; control->rs2 = opcode & 0x1f; control->disp22 = opcode & 0x3fffff; control->disp30 = opcode & 0x3fffffff; control->cond = (opcode >> 25) & 0xf; } void addi(struct CPU */*cpu*/, u32 /*rd*/, u32 /*rs1*/, i32 /*signedImm*/) { // XXX FILL THIS IN } bool execute(struct CPU */*cpu*/, struct control_signals */*control*/) { // XXX FILL THIS IN return true; } string prompt(const char *str) { string ret; cout << str; cout.flush(); cin >> ret; return ret; } void fillState(char *fileName, void *buf, int size) { int ret, fd; assert(size > 0); fd = open(fileName, O_RDONLY); assert(fd >= 0); ret = read(fd, buf, size); assert((ret == size) && (ret>0)); close(fd); } void cpu_exec(struct CPU *cpu) { struct control_signals *control = new struct control_signals; u32 opcode; bool runSimulation = true; while(runSimulation && !userQuit) { opcode = fetch(cpu); decode_control_signals(opcode, control); // second part of decode and write back also runSimulation = execute(cpu, control); } if(userQuit) { } } int main(int argc, char *argv[]) { ifstream infile; struct CPU *cpu; if(argc < 2) { cerr << "Usage: " << argv[0] << " memory_file [cpu_file]" << endl; return -1; } signal(SIGINT, ctrlC); // initialize our state ram = new uint8_t[RAM_SIZE]; cpu = new struct CPU; for(int idx = 0; idx < NUM_REGS; idx++) { cpu->regs[idx] = 0; } cpu->pc = 0; cpu->branch_pc = (u32) -1; // setup the stack pointer cpu->regs[14] = RAM_SIZE-4-120; // setup the fib program cpu->regs[8] = RAM_SIZE-4; // fetch our memory image and cpu state (if set) fillState(argv[1], ram, RAM_SIZE); if(argc >= 3) { fillState(argv[2], cpu, sizeof(struct CPU)); } startTime = time(NULL); cpu_exec(cpu); return 0; }