Fall 2000 |
Project 4: Simulator |
CS61C (Patterson) |
Project policy:
You may work in groups of two students(partners don't have to be in the same lab section),
But be sure to indicate your partner on your project submission.
Project is due Friday, October 20, 2000 at 11:59:59 PM PDT.
Overview and getting started:
In project 3, you created a disassembler for a subset of the MIPS
instruction set. In this project, you will create an instruction
simulator for a subset of the MIPS instruction set. Your simulator
will fetch, decode and execute MIPS machine instructions. Your
disassembler did the fetching and decoding, but for this project,
instead of printing the instructions, you will perform the actual
operation (indicated by the instructions) on the machine state. You
are creating what is effectively a miniature version of spim! (There
is one important difference tough--spim takes in assembly language
source files, not ".dump" files, so it performs many of the functions
of an assembler in addition to being a simulator.)
You should make a directory in your home directory named proj4, and
copy all the files from ~cs61c/proj4 into your proj4 directory. Run
make to compile your project. It will create sim for you.
Project Submission:
Make sure you are in your proj4 directory
type in
submit proj4
You only need to submit the computer.c file.
Assignment:
Part 1: regular instructions
The files sim.c, computer.h, and computer.c comprise the framework for
a MIPS simulator. Complete the program by filling in appropriate procedures in
computer.c; it should be the only file you modify. Your simulator must
be able to simulate the machine code version of the following MIPS
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, Rsrc1, imm
- or Rdest, Rsrc1, Rsrc2
- ori Rdest, Rsrc1, imm
- lui Rdest, imm
- slt Rdest, Rsrc1, Rsrc2
- beq Rsrc1, Rsrc2, address
- bne Rsrc1, Rsrc2, address
- j address
- jal address
- jr Rsrc
Part 1 does not involve instructions that access memory
(loads and stores); all computations are done in the registers.
Part 2: memory access
Add support for two more instructions:
- lw Rdest, offset(Radd)
- sw Rsrc, offset(Radd)
With these additions, the program can simulate real programs that do
just about anything that can be done on a real MIPS processor (with
the notable exceptions of floating-point math and interrupts).
How does the code work?
The framework code begins by doing the following:
- It reads the machine code into "memory", starting at "address" 0x00400000.
In keeping with the SPIM 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 as in project 3.
- It initializes the stack pointer to 0x00404000, the program counter
to 0x00400000, and all other registers to 0x0000000.
- It sets flags that govern how the program interacts with the
user (see below).
-
It then enters a loop that repeatedly fetches and executes instructions.
Your job is to provide the code for the Disassemble, Decode, Execute, Mem,
and RegWrite functions, plus any auxiliary functions that are appropriate.
-
It provides simulated data memory starting at address
0x00401000 and ending at address 0x00404000. It stores instructions
together with data in the same memory array. You may assume that the
simulated instructions will not address memory illegally. An
instruction not among those listed above should cause the program to
terminate gracefully.
The framework code support several command line options:
- -i : runs the program in "interactive mode". In this mode, the program
prints a ">" prompt and wait for you to type a return before simulating each
instruction. If you type a "q" (for "quit") followed by a return, the
program exists. 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 in the previous section.
- -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 a branch, a jump, or a store, which doesn't affect any
registers, the framework code prints a message saying that no registers
were affected. (Hint: 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's not sw, the framework code prints a message saying
that no memory locations were affected. (Hint: Your code needs
to signal when a simulated instruction does not affect memory, by
returning an appropriate value in the changedMem argument to Mem.)
- -d : is a debugging flag that you might find useful. All the printing in
the framework code is done in the PrintInfo function. You will need to
supply a Disassemble function that will also do some printing.
Please do not change the framework code.
Testing:
We have provided two tests for you: test1 includes most of the
instructions you need to implement for part 1; test2 includes some of
those instructions, plus the memory access instructions. For each
test (test1 and test2) there are actually three files: testN.s, which is
the assembly code; testN.dump, which is the binary code your simulator
will take as input; and testN.out, which is the correct output for
your simulator. You can run the tests separately by typing make
test1 or make test2. When you are fairly certain
everything works, you can run them consecutively by typing make
test. The test files do not include all the instructions you
need to implement, and this is done on purpose. You should be able to
easily create your own test files (by writing .s files and dumping
them using spim) and test your code thoroughly.
Submit Project:
The following file is required for successful submission:
Final Remarks:
Programs that run under this simulator also run under spim. However,
there are a few rules you need to follow if you'd like to write your
own MAL program that run both under this small simulator and under
spim:
- Do not depend on any assembler directives. In particular, you can't use
directives to set up memory. Instead, you must write MIPS code yourself
to set up any values in memory that you need to use.
- Do not use spim's normal data-memory section (0x10000000 to 0x10001000) or
rely on the fact that the stack is between 0x7fff0000 and
0x80000000. instead, simply assume that $sp ($29) is in a reasonable place
when your program begins. If you need "global" data memory, use the global pointer ($gp) by doing the
following: $gp = $sp - 0x2000 and then use addresses offset from $gp.
- Basically, do not use absolute addresses except the addresses of instructions.
- Obviously, do not use any instructions that aren't implemented by your simulator.
Watch out for MAL instructions that
expand to multiple TAL instructions; you may not have implemented some of
the expanded instructions. You can load the MAL source file in xspim to
see how the instructions are translated.
To get your MAL code working correctly with this project, do the following:
- Write your MAL code normally.
- Create the dump files in spim, which you can load into your simulator.
If your MAL code runs under spim but not in your simulator, it either
means you did not follow the above rules or your simulator has a bug in it, or both. :o)
REMEMBER: the grading will be done almost entirely by automated
scripts. Your output must exactly match the specification, which makes
correctness the primary goal of this project. Make sure you know
exactly how to output all kinds of instructions.
Feedback:
Please send your comments about the content and the format of project 4
to: cs61c-td@cory.eecs.berkeley.edu
Last updated: 10/06/2000 by cs61c-td