Question
Hello, I need some help finishing this task. Here is what should be done: Using the sample code for the single cycle machine provided as
Hello,
I need some help finishing this task.
Here is what should be done:
"Using the sample code for the single cycle machine provided as reference for this module, create a complete program. Including:
1. A method for reading program instructions and data into their respective memories. This function will take as an input parameter, the name of a text file (alternately, you may inline this function in main).
The contents of the file will consist of three hexadecimal numbers delimited by spaces. The first number will be 8 characters and will correspond to the byte memory address to place the data in. The next number will either be a 1 (for program memory), or a 0 (for data memory). The last number will be 8 characters that will correspond to data to place at the specified memory address. The lines may also contain comments which always begin with the # symbol.
Examples:
000C0DE0 1 11112222 # this line places 0x11112222 at program memory space 0x000C0DE0 00012340 0 0000F00D # this line places 0x0000F00D at data memory space 00012340
Note: All addresses will be word-aligned and accesses will always be 32-bits at a time, so endianness of how you store the data should not matter.
Note: You may want to use the functions Cpu.setImem() and Cpu.setDmem() to help with this function
2. Complete required macro definitions within Cpu.cpp (the area is marked by comments within the file). You will need to apply your knowledge of instruction decoding the MIPS architecture and bitwise operations to do this.
3. Instrument the Cpu.update() function in order to gather information on the following.
The total number of cycles executed
The total number of cycles where memory is accessed
The total number of cycles where data is written back to the register file
3. Write a main function that prints a startup banner (includes your name and course number), reads the input file, initializes memory, runs the simulation, and displays results. When simulating, execution will begin at instruction 0 and should execute for 270 cycles.
Upon completion of the simulation, your code should dump the contents of the registers in hexadecimal format and show the count values in decimal (you may choose to modify the CPU::dump() function for this. Example program output is shown below (your numbers will be different). "
The Cpu.cpp should be modified, and main.cpp should be created.
my work so far:
Cpu.cpp #include
/************************************************************************* * Student modifications should go here to give the proper values for these * macro definitions **************************************************************************/ // BITS(x, start, end) a macro function that takes three integer arguments // the output of the function will be bits start-end of of value x but // the bits in the output will be shifted so that bit start is at bit // position 0. Example: the input values 0x12345678, 8,12 will yield // the result 0x00000016 #define BITS(x,start,end) (((0xFFFFFFFF >> (31-end)) & x) >> start)
// SIGN_EXT(x) a macro to sign extend a 16 bit signed integer to 32 bits #define SIGN_EXT(x) ((x & (1<<15))) ? 0xFFFFFFFF & x : 0x0000FFFF & x
// each of the following are the opcodes for teh specified instruction from // the MIPS instruction set. #define OP_LW 0x23 #define OP_SW 0x2B #define OP_RTYPE 0x00 #define OP_BEQ 0x04 #define OP_JMP 0x02
//declare variable int num = 0; int num_r = 0; int num_m = 0;
//******************************************** // Constructor // initialize the cpu object Cpu::Cpu() { // initialize the program counter to 0 pc = 0; }
//******************************************** // setImem // set the value of a 32-bit word at a specified // address in the CPU's instruction memory void Cpu::setImem(unsigned int address,unsigned int value) { imem.setAt(address,value); }
//******************************************** // setImem // set the value of a 32-bit word at a specified // address in the CPU's data memory void Cpu::setDmem(unsigned int address, unsigned int value) { dmem.update(address, value, true); }
//************************************************* // update() // This function simulates a single clock cycle of the // CPU. This was covered in the class lecture notes void Cpu::update() { // calculate the combinational logic values - these become stable // some amount of time after the previous system clock.
// fetch the current instruction unsigned int instruction = imem.value(pc);
// extract the fields from the instruction unsigned int opcode = BITS(instruction, 26, 31); unsigned int funct = BITS(instruction, 0, 5); unsigned int rdidx = BITS(instruction, 11, 15); unsigned int rtidx = BITS(instruction, 16, 20); unsigned int rsidx = BITS(instruction, 21, 25); signed int immed = SIGN_EXT(BITS(instruction, 0, 15)); unsigned int jmpaddr = BITS(instruction, 0, 25);
// alu operation combinational logic int ALUOp = 0x0; if ((opcode == 0x23) || (opcode == 0x2b)) ALUOp = 0x0; // load or store instructions if (opcode == 0x04) ALUOp = 0x1; // branch on equal instruction if (opcode == 0x00) ALUOp = 0x2; // r-type instructions // alu control combinational logic int ALUControl = 0xF; if (ALUOp == 0x0) ALUControl = 0x2; // lw/sw -> add if (ALUOp == 0x01) ALUControl = 0x6; // lw/sw -> subtract if (ALUOp == 0x02) { if (funct == 0x20) ALUControl = 0x2; // add if (funct == 0x22) ALUControl = 0x6; // subtract if (funct == 0x24) ALUControl = 0x0; // AND if (funct == 0x25) ALUControl = 0x1; // OR if (funct == 0x2a) ALUControl = 0x7; // set-on-less-than }
// additional control signals based on opcode unsigned int aluSrc = (opcode == OP_LW) || (opcode == OP_SW) ? 1 : 0; unsigned int regDest = (opcode == OP_RTYPE) ? 1 : 0; unsigned int branch = (opcode == OP_BEQ) ? 1 : 0; unsigned int memRead = (opcode == OP_LW) ? 1 : 0; unsigned int memToReg = (opcode == OP_LW) ? 1 : 0; unsigned int memWrite = (opcode == OP_SW) ? 1: 0; unsigned int regWrite = (opcode == OP_LW) || (opcode == OP_RTYPE) ? 1 : 0; unsigned int jump = (opcode == OP_JMP) ? 1 : 0;
// register file read operation based on rt and rd indicies unsigned int regRs = regs.readData1(rsidx); unsigned int regRt = regs.readData2(rtidx);
// alu source selection multiplexor unsigned int operand1 = regRs; unsigned int operand2 = aluSrc ? immed : regRt;
// ALU combinatinational logic int ALUResult = 0; if (ALUControl == 0x0) ALUResult = operand1 & operand2; // and if (ALUControl == 0x1) ALUResult = operand1 | operand2; // or if (ALUControl == 0x2) ALUResult = operand1 + operand2; // add if (ALUControl == 0x6) ALUResult = operand1 - operand2; // subtract if (ALUControl == 0x7) ALUResult = (operand1 < operand2) ? 1 : 0; // set less than if (ALUControl == 0xc) ALUResult = ~(operand1 | operand2); // nor int zero = (ALUResult == 0x00000000) ? 1 : 0; // read the data memory if required unsigned int memData = dmem.read( ALUResult, memRead);
// register write data multipelexor unsigned int regWrData = memToReg ? memData : ALUResult; // register write destination multiplexor unsigned int regWrAddr = regDest ? rdidx : rtidx;
// calculate the branch or jump address unsigned int branchAddr = ( immed << 2) + pc + 4; unsigned int fullJumpAddr = (( pc + 4 ) & 0xF0000000) | (jmpaddr << 2); unsigned int next_pc;
// multiplexors to select the next program counter value next_pc = (branch && zero) ? branchAddr : pc + 4; next_pc = (jump) ? fullJumpAddr : next_pc;
// update the cpu state based on the rising edge of the system clock // in real hardware, these updates would all happen simultaneously regs.update(regWrAddr,regWrData,regWrite); dmem.update(ALUResult,regRt,memWrite); pc = next_pc;
/****************************************************************** * STUDENT CODE * Instrument the CPU here to count the total number of instructions, * the total registesr write instructions, and the total memory * instructions ******************************************************************/ num++; if(regWrite) num_r++; if(memRead || memWrite) num_m++; }
//********************************************************************** // dump() // dump the state of the CPU object to the standard output device void Cpu::dump() { printf("PROGRAM COUNTER = %08x INSTRUCTION = %08x ",pc, imem.value(pc)); printf("REGISTER FILE "); regs.dump(); printf(" ");
/***************************************************************** * STUDENT CODE * This would be a great place to output your instrumention results ******************************************************************/ Here is where I need some help }
And I need the driver file main.cpp which will print the results.
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started