CS 61C Fall 2010 Project 1: MIPS Instruction Set Emulator

TA: Michael Greenbaum

Part 1 Due 23:59:59pm, Saturday, September 18, 2010.

Part 2 Due 23:59:59pm, Saturday, September 25, 2010.

Last Updated: 9:45 pm, Wednesday, Septmber 22, 2010


Getting started

This is an individual assignment; you must work alone.

Copy the directory ~cs61c/proj/01 to your home directory and name it "proj1". It includes several files: sim.c, computer.h, computer.c, sample.s, sample.dump, sample.output and makefile. These are described below.


In this project, you will create an instruction interpreter for a subset of MIPS code. Starting with the assembled instructions in memory, you will fetch, disassemble, decode, and execute MIPS machine instructions, simulating each stage in the computation. You're creating what is effectively a miniature version of MARS! There is one important difference, though—MARS takes in assembly language source files, not .dump files, so it contains an assembler, too.

The MIPS green sheet provides information necessary for completing this project


The files sim.c, computer.h, and computer.c comprise a framework for a MIPS simulator. Complete the program by adding code to computer.c. Your simulator must be able to simulate the machine code versions of the following MIPS machine instructions:

	addu	Rdest, Rsrc1, Rsrc2
	addiu	Rdest, Rsrc1, imm
	subu	Rdest, Rsrc1, Rsrc2
	sll	Rdest, Rsrc, shamt
	srl	Rdest, Rsrc, shamt
	and	Rdest, Rsrc1, Rsrc2
	andi	Rdest, Rsrc, imm
	or	Rdest, Rsrc1, Rsrc2
	ori	Rdest, Rsrc, imm
	lui	Rdest, imm
	slt	Rdest, Rsrc1, Rsrc2
	beq	Rsrc1, Rsrc2, raddr
	bne	Rsrc1, Rsrc2, raddr
	j	address
	jal	address
	jr	Rsrc
	lw	Rdest, offset (Radd)
	sw	Rsrc, offset (Radd)

Once complete, your solution program will be able to simulate real programs that do just about anything that can be done on a real MIPS, with the notable exceptions of floating-point math and interrupts.

The framework code

The framework code begins by doing the following.

  1. It reads the machine code into "memory", starting at "address" 0x00400000. (In keeping with the MARS convention, addresses from 0x0000000 to 0x00400000 are unused.) We assume that the program will be no more than 1024 words long. The name of the file that contains the code is given as a command-line argument.

  2. It initializes the stack pointer to 0x00404000, it initializes all other registers to 0x00000000, and it initializes the program counter to 0x00400000.

  3. It provides simulated data memory starting at address 0x00401000 and ending at address 0x00404000. Internally, it stores instructions together with data in the same memory array.

  4. It sets flags that govern how the program interacts with the user.

It then enters a loop that repeatedly fetches and executes instructions, printing information as it goes:

The framework code supports several command line options:

  -i   runs the program in "interactive mode". In this mode, the program prints a ">" prompt and waits for you to type a return before simulating each instruction. If you type a "q" (for "quit") followed by a return, the program exits. If this option isn't specified, the only way to terminate the program is to have it simulate an instruction that's not one of those listed on the previous page.
  -r   prints all registers after the execution of an instruction. If this option isn't specified, only the register that was affected by the instruction should be printed; for instructions which don't write to any registers, the framework code prints a message saying that no registers were affected. (Your code needs to signal when a simulated instruction doesn't affect any registers by returning an appropriate value in the changedReg argument to RegWrite.)
  -m   prints all data memory locations that contain nonzero values after the execution of an instruction. If this option isn't specified, only the memory location that was affected by the instruction should be printed; for any instruction that doesn't write to memory, the framework code prints a message saying that no memory locations were affected. (Your code needs to signal when a simulated instruction doesn't affect memory by returning an appropriate value in the changedMem argument to Mem.)
  -d   is a debugging flag that you might find useful.

Your Job

Your job in this project is to implement the Decode, Execute, Mem, and RegWrite functions, which correspond with the stages of a MIPS archetecture, as well as the UpdatePC and PrintInstruction functions. We divide the tasks of this project into two (unequal) parts, each due a week apart, plus optional extra credit. We'll present the breakdown of parts in the next section.

As discussed in lecture, Fetch, Decode, Execute, Mem, and RegWrite are the five processing stages of the MIPS archetecture. In our simulator, these steps involve completing the following tasks. The Fetch step has been implemented for you:

In the case of an unsupported instruction, make sure that you call exit(0) somewhere in your code, before PrintInfo and fetching the next instruction. Do not print any special error message in this case.

It is important that you follow this instruction breakdown, as we will be grading your project partially on the input/output behavior of these functions.

In the UpdatePC function, you should perform the PC update associated with the current instruction. For most instructions, this corresponds with an increment of 4 (which we have already added).

The PrintInstruction function prints the current instruction and its operands in text. We will be grading your project with automated scripts, therefore the output must follow this part of the specification exactly. Here are the details on the output format: