Question: File : Cpu.cpp #include #include Cpu.h /************************************************************************* * Student modifications should go here to give the proper values for these * macro definitions **************************************************************************/ //




File : 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)
// SIGN_EXT(x) a macro to sign extend a 16 bit signed integer to 32 bits #define SIGN_EXT(x)
// each of the following are the opcodes for teh specified instruction from // the MIPS instruction set. #define OP_LW #define OP_SW #define OP_RTYPE #define OP_BEQ #define OP_JMP
//******************************************** // 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
// 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
// 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 ******************************************************************/ }
//********************************************************************** // 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 ******************************************************************/ }



input.txt






The use of simulation and models to help drive business decisions is commonplace in the technology sector. Based on your knowledge of the MIPS architecture, you will complete a small simulator to gather key information about the single cycle processor running a company-specific benchmark. Context A startup company that you are associated with, SensoMIPS, is contemplating innovative ways to improve performance per Watt of power consumption for MIPS-based microcontrollers. Their target market is Internet of Things (loT) embedded computing applications where size, weight and power (SWAP) are important. SensoMIPS hardware engineers understand that the longest combinational logic path through the processor will limit the clock speed for all instructions. This means that the LW instruction for the MIPS processor dictates the processor clock frequency. The engineers have proposed a hypothetical new method that they call "non-uniform-clocking" which allows longer clocks to be applied to the processor only for instructions that need it. The engineers, however, need some analysis to determine how much benefit, if any, this will yield in terms of increased performance, and increased performance per Watt of power consumed. Your job is to complete a small simulator of the architecture and use it to gather the necessary information. Learning Objectives At the end of this project, you will be able to: - Implement a simulator of the single-cycle MIPS architecture - Gather processor utilization metrics based on real code. - Quantify trade-offs related to single-cycle machine architecture utilization, performance, and power. Please use the following resources when completing this project. - project_4a_code.zip C++ starting point for this project. You will need to create your own main function and modify Cpu.cpp (and maybe Cpu.h). All the other files are required but should not be modified. - input.txt - the input file to "run" on the simulator - Project 4a.doc A. Complete the following table of instruction counts for the single cycle simulator. B. Clocks Per Instruction for Single Cycle Architecture C. If writing back to the register file takes 10% of the clock period and memory instructions take 30% of the clock period, find the new average clock period for your code if a "non-uniform-clocking" architecture is used. Express your result at a percentage of the original clock period Hint: the percentage of instructions that don't use memory will reduce the clock period by 30%, and the percentage of instructions that don't write to the register file will reduce the clock period by 10%. D. What is the speedup that can be expected with "non-uniform-clocking"? Step IV: Business Impact A. The target customers for SensoMips are concerned about performance per Watt of power consumption. Power consumption of the current chip is 500 milliWatts. If power consumption of the new chip is 550 milliwatts plus 5 milliWatts for every percent of additional clock frequency, what is the power consumption of the new chip? (lower power consumption is better) What is the performance per watt of the new processor concept relative to the current generation? (higher performance per Watt is better) Based on your analysis, what is your recommendation to SensoMIPS? \#include "DataMemory. h " \#ifndef DATAMEMORY_H \#define DATAMEMORY_H class DataMemory \{ public: void update(unsigned int address, unsigned int data, bool write); unsigned int read(unsigned int addr, bool read); protected: private: unsigned char memory[2048]; \} \#endif // DATAMEMORY_H \#include "InstructionMemory.h" \#ifndef INSTRUCTIONMEMORY H INCLUDED \#define INSTRUCTIONMEMORY H INCLUDED class InstructionMemory \{ public: unsigned int value(unsigned int pc); void setAt(unsigned int addr, unsigned int value); private: unsigned int memory[2048]; \} \#endif // INSTRUCTIONMEMORY H INCLUDED *********************************************************************************************/ \#include \#include "RegisterFile.h" //**************************************************************************** // update() // write new data to the specified address if the write signal is true void RegisterFile: : update (unsigned int addr, unsigned int data, bool write) \{ if (write) \{ regs [ addr ]= data; \} \} / / readData1() I/ return the value of the indexed register unsigned int RegisterFile: : readData1 (unsigned int addr) \{ return regs [addr]; \} I / readData2() I/ return the value of the indexed register unsigned int RegisterFile: readData2 (unsigned int addr) \{ return regs [addr]; \} I/****************************************************************************** //dump() I/ dump the conents of the register file to the standard output device II in a human readable fashion. void RegisterFile:: dump (void) \{ for (unsigned int i=0;i
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
