CS3410 Fall 2016
Schedule design doc meeting by: 11:59pm, Friday, September 16th, 2016
Preliminary Design documentation Due: 11:59pm, Thursday, September 22nd, 2016
Project Due: 11:59pm, Monday, October 3rd, 2016
Late Policy: Slip days can be used for the final submission but not for the design doc submission.
If a slip day is used, it will be used for both partners.
You must work with the same partner for this project and the next. You can change partners for the later projects.
Warning: Read the ENTIRE writeup before you begin. Be sure to keep backups of your circuit, and do not use the merging functionality in Logisim, as it has been known to delete entire circuits.
In this and the next project we will implement a subset of the MIPS32 architecture in Logisim. We will ignore more advanced features such as the MIPS coprocessor instructions and traps/exceptions for these assignments.
In this project you will implement a functioning outline of the pipelined processor for a small set of instructions, including: decoding all the instructions you will encounter in this and the next proejct, implementing most of the MIPS pipeline, correct implementation of arithmetic and logic operations, and simple hazard avoidance for these instructions. In the next project you will implement a more complete set of instructions, and add more complete hazard logic.
Academic Integrity. As one of the most widely studied architectures, MIPS has a wealth of information available on the web and in textbooks. You may consult any MIPS documentation available to you in order to learn about the instruction set, what each instruction does, etc.; however, we expect your design to be entirely your own, and your submission should cite any significant sources of information you used. If you are unsure if it is okay to borrow from some other source, just ask the TAs. If you are hesitant to ask the TAs or to cite the source, then it is probably not okay. Plagiarism in any form will not be tolerated. It is also your responsibility to make sure your sources match the material we describe here (warning: the top Google hit for "MIPS reference" contains several inaccuracies).
You will implement a five-stage MIPS pipeline, which is the most common organization for MIPS and is similar to what is described in the book and in class:
The MIPS standard, volume I, section 2.6, describe several possible MIPS pipelines, none of which exactly match the five-stage pipeline that we will implement.
Memory stage. For this project, the memory stage of the pipeline will just be a passthrough doing nothing. In the next project you will implement load and store memory operations and populate the memory stage part of the pipeline.
Delay slot. In this assignment you will not implement the branch/jump delay slot or memory load delay slot. That will be added in the next project.
Implement a five-stage pipelined MIPS processor in Logisim. Your design should contain a program counter, a read-only program memory (ROM), a register file, our ALU, and any other components needed, along with the instruction decode and control circuits needed to connect them all together. The pipeline should: fetch instructions to execute from the program ROM and increment the program counter by 4; decode each instruction; select arguments from the register file; compute results; do nothing in the memory stage; and store results back in the register file.
Your pipeline must correctly execute all of the instructions in Table A:
Table A | |
---|---|
Immediate arithmetic | ADDIU, ANDI, ORI, XORI, SLTI, SLTIU |
Register arithmetic | ADDU, SUBU, AND, OR, XOR, NOR, SLT, SLTU |
Move | MOVN, MOVZ |
Shifts (constant and variable) | SLL, SRL, SRA, SLLV, SRLV, SRAV |
Immediate load | LUI |
Note that LUI doesn't access memory and so, despite its name, is more similar to an arithmetic or logic instruction than a memory load instruction.
Table B contains instructions which you will be implementing in the next project. These instructions should be nonfunctional in this project, so your instruction decoding and control logic must be able to recognize table B instructions, and ensure that they have no effect on the program execution. Since you will be implementing the functionality of these instructions in the near future, decoding them properly now will save you from having to completely re-implement your decoding and control logic later.
Table B | |
---|---|
Jumps (with one delay slot) | J, JR, JAL, JALR |
Branches (with one delay slot) | BEQ, BNE, BLEZ, BGTZ, BLTZ, BGEZ |
Memory Load/Store (little endian) | LW, LB, LBU, SW, SB |
Our testing programs for this project will include a mixture of instructions from both Table A and Table B. When processing one of the instructions of Table B, your implementation is free to do anything as long as: (1) no value in the register file changes and (2) the execution of instructions from Table A are not interfered with in any way. Think carefully about your decode logic to make sure this second condition works out.
Deviation from the MIPS standard: You can ignore any MIPS instruction or feature not mentioned in this document, such as traps, exceptions, and system calls. You can also assume that your processor will never encounter anything but legal instructions from the lists above.
Refer to the MIPS manual, Volume 2, linked on the course web site for a full specification of what each of these operations does. Except where noted in here, the MIPS manual is the authoritative specification for this project: information you find elsewhere (e.g. Wikipedia or the book) doesn't count if it contradicts the MIPS manual.
Data Hazard: The trivial solution to data hazards is, of course, stalling. However, the performance of trivial solutions is not optimal. Implement forwarding such that your implementation will handle data hazards without sacrificing performance.
Build your MIPS processor as a single Logisim circuit file. Do not use Logisim's Project > Load Library > Logisim Library command to import circuits from other Logisim files.
Your top-level circuit must be named either "MIPS" or "MIPS32" (case-sensitive).
The "CS3410 Components" library folder contains several components you will need, such as a register file, an ALU, an incrementer, and a program memory. You must use these components where applicable, but you may only use one of each.
Register file. Don't attempt to create your own register file out of regular Logisim Registers. This one makes debugging and simulation much easier.
ALU. You must use the ALU from this library, rather than your ALU from project 1. Your design may only contain one ALU.
MIPS Program ROM. We will implement a Harvard Architecture design: The Program ROM component will store a read-only copy of the program instructions, and (in the next project) you will use a separate Logisim RAM to store data. The Program ROM component can load and display MIPS assembly language, which helps with debugging and saves you from having to write test programs in machine language.
Incrementer. You must use one (and only one) of these to increment the PC. Note that the incrementer only computes +1, whereas the PC increments by 4.
Logisim components. You can additionally use any of the components that come with Logisim, such as a Register for the PC, multiplexers, and so on.
Write a test program file for Logisim containing MIPS assembly that fully tests all aspects of your processor; it should be able to be run by loading it into the Program ROM. The test program should demonstrate that the processor's behavior conforms to all specifications given here and in the MIPS reference manual. This is a critical step, and you should spend a fair amount of time developing a comprehensive test program that exercise all of the different instructions and features of your processor. The program should be well commented, indicating what it is doing and what results should be expected when running the tests, so that the course staff is convinced of the correctness of your processor. All test cases should be included in a single file, and the quality and thoroughness of the tests will be graded.
Since the MIPS processor does not use input and output pins in the same way as the ALU, you will not be able to test your cicuit as a whole using test vectors. You must use your MIPS test program to evaluate the correctness of your processor. However, test vectors may be useful for debugging some of your subcircuits.
Don't forget to include every possible instruction in your testing program. This includes table B instructions; you must ensure that your processor does nothing when executing any table B instruction, as required.
The design document should include a block diagram showing all the major components in the processor (ALU, Register File, PC, pipeline registers, etc.), and the datapath connections between them. You need not completely draw wires for control logic signals, but should indicate which components take control inputs, and give names to all control signals. Overall, the diagram should be very similar to (and not much more complicated than) the diagrams used in lecture, but with labels for control signals and any relevant data signals. You should provide an explanation for any parts of your processor or any subcomponents that are unusual or potentially confusing.
Also include a description of your control and instruction decoding logic. For each control logic signal (or group of related control logic signals) you should provide (a) a brief description of what the signal does, e.g. what the values of the control signal mean; and (b) a truth table showing what value the signal takes for each possible opcode.
While the handling of the instructions in Table B will not be graded in the design document, it is recommended to start thinking about how you will handle the execution of these instructions. The design document meeting is your chance to ask a TA any questions you may have about this and the next project (where you will implement the rest of the instructions).
You will need to submit a preliminary design document by 11:59pm, September 22nd, 2016 via CMS. You also need to schedule a meeting with one of the TAs to discuss about your intended design. The time schedule is available on CMS. Pick one that works for you and your partner. During the meeting, you will need to bring your printed design document, and be prepared to present your design to TA.
Update your design document as you work on your circuit. Documentation provides you another avenue of communicating your intended design and implementation in the case your circuit has mistakes. For a well-designed, clearly labeled and nicely laid out, completely correct solution, a screenshot of the Logisim circuit itself can serve as a diagram, but, otherwise, use the documentation to clarify and explain any parts of your circuit we might find confusing.
We have provided a design doc guideline and template to help you with writing the design documentation. The tex source file and Makefile are available here.
Note the different due dates
Help. Ask the instructor, TAs and consultants for help We also expect to see most students in office hours during the course of the project. Extra hours will be scheduled as needed. Also check Piazza for more help.
Bugs. If you suspect a bug in Logisim or the cs3410 library, ask the course staff for help.
Really, it shows. Do a pencil-and-paper design before implementing in Logisim. We will penalize poorly laid-out designs that are hard to understand.
What to do first. Don't wait to get started. However, because we are still covering pipelining and pipeline hazards in lecture, you probably will not want to start right in on the final design. The following order of operations might be sensible:
Ensure that your circuit sticks to the following rules, as well as the 3410 Logisim design guidelines to avoid losing points!
3410 Components. Do not duplicate any of the provided 3410 components in your circuit. At most one of each should be used. Note that duplicates of some of the components, such as the register file, will break the autograder, even if placed in an unused subcircuit, so ensure that any extras are removed before submission to avoid losing points.
Clock. You should only have one clock in the entirety of your circuit. Subcircuits requiring a clock signal should use input pins to connect to the processor clock. Your MIPS design should use a rising clock edge to define the boundaries of clock cycles: during the first half of each processor clock cycle the clock is 1; during the second half of each cycle the clock is 0; and the end of the cycle is when clock transitions from 0 to 1. By default, most Logisim memory components (Registers, D Flip-Flops, etc.) are triggered on the rising clock edge, so you can leave them as is. The register file is the only component that may use a falling clock edge, and can be so configured using the attributes panel. In order to avoid read-write hazards, you will either want to change this setting, or negate the clock signal going into the register file (think about why this works).
Comparators, found in the Arithmetic folder in Logisim, may be useful for implementing some of the functionality of the processor. You are allowed to use at most two comparators in your circuit. Points will be deducted if you use more than two comparators.
Demultiplexors should not be needed for this project, and you should avoid using them.
Tunnels, if used at all, should be used sparingly and only when they make your circuit significantly easier to read.
You may find that combinational analysis is useful in designing your instruction decoding logic
Notes on implementing SLTI and SLTIU: The immediate value in these instructions should be sign-extended. The MIPS handbook describes the operation of SLTIU as sign-extending the immediate value first, and then comparing the immediate to Rs both as unsigned integers. As a result, you're limited to
representing the minimum or maximum of the range of representable integers:
0x0000 to 0x7fff turn into 0x00000000 to 0x00007fff: This is 0 to 32767.
0x8000 to 0xffff turn into 0xffff8000 to 0xffffffff: This is maxint-32767 to maxint, where maxint = 2^32 - 1.
For details please refer to MIPS handbook Vol 2, page 204 ~ 205.
Additionally, note that there are some typos in MIPS Reference Vol. 2 pages 196 and 197.
For instructions SLTI and SLTIU, each GPR[rd] should be replaced with a GPR[rt] in the explanation in the Operation section.
The "CS3410 Components" library will only appear if you are using the most recent version of Logisim, downloaded from the course website. Please ensure that you are using the correct version. If so, you should have a folder in your sidebar containing the following components:
Register File. A 32-bit wide by 32-registers deep register file. Register |
|||||||||||||||||||||||||||||||||||||||||||
MIPS Program ROM. A 32-bit wide byte-addressed ROM, with built-in MIPS assembler. Use the attributes
panel to load a MIPS assembly file into the ROM. The |
|||||||||||||||||||||||||||||||||||||||||||
MIPS ALU. Computes a result as follows. You do not need to test the provided ALU, and can assume it will work exactly as specified.
|
|||||||||||||||||||||||||||||||||||||||||||
Incrementer. An adjustable-width incrementer. Takes its input |
|||||||||||||||||||||||||||||||||||||||||||
LCD Video. If |
1a. EX/MEM.RegisterRd == ID/EX.RegisterRs 1b. EX/MEM.RegisterRD == ID/EX.RegisterRt 2a. MEM/WB.RegisterRd == ID/EX.RegisterRs 2b. MEM/WB.RegisterRd == ID/EX.RegisterRtTo resolve the first two data hazards, we can forward value from the EX/MEM pipeline registers. To resolve the latter two hazards, we can forward value from the MEM/WB pipeline registers. In order to figure out the correct forwarding control logic, we note that forward will happen:
1. only if the forwarding instruction will write to a register EX/MEM.Regwrite, MEM/WB.Regwrite 2. AND only if Rd for that instruction is not $zero EX/MEM.RegisterRd != 0, MEM/WB.RegisterRd != 0 3. AND only if forwarding instruction is not a load in MEM stage EX/MEM.MemRead == 0From the above, we can derive the following forwarding conditions:
if (EX/MEM.RegWrite and (EX/MEM.RegisterRd != 0) and (EX/MEM.RegisterRd == ID/EX.RegisterRs)) ForwardA = 10 if (EX/MEM.RegWrite and (EX/MEM.RegisterRd != 0) and (EX/MEM.RegisterRd == ID/EX.RegisterRt)) ForwardB = 10MEM Hazard
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd != 0) and (MEM/WB.RegisterRd == ID/EX.RegisterRs)) ForwardA = 01 if (MEM/WB.RegWrite and (MEM/WB.RegisterRd != 0) and (MEM/WB.RegisterRd == ID/EX.RegisterRt)) ForwardB = 01However, if we have a sequence of code that causes both data hazards to happen:
add $1, $1, $2 sub $1, $1, $3 or $1, $1, $4then we want to use the most recent result--the result from the sub instruction.
if (MEM/WB.RegWrite and (MEM/WB.RegisterRd != 0) and not (EX/MEM.RegWrite and (EX/MEM.RegisterRd != 0) and (EX/MEM.RegisterRd == ID/EX.RegisterRs)) and (MEM/WB.RegisterRd == ID/EX.RegisterRs)) ForwardA = 01 if (MEM/WB.RegWrite and (MEM/WB.RegisterRd != 0) and not (EX/MEM.RegWrite and (EX/MEM.RegisterRd != 0) and (EX/MEM.RegisterRd == ID/EX.RegisterRt)) and (MEM/WB.RegisterRd == ID/EX.RegisterRt)) ForwardB = 01Note that the forward condition for MEM hazard on page 369 in the revised 4th edition textbook (and earlier versions) is WRONG! Starting in the 5th edition (page 311), it is correct.
The MIPS Program ROM component has a built-in assembler that understands all of the instructions you will
implement. The syntax is standard MIPS syntax. Labels are case sensitive, everything else ignores case. Anything
following a pound ('#
') is a comment. In this project, you will only use a few of the instructions listed
here.
The instruction syntax is the same as given in the MIPS standard (and different from the output of gcc
and
many other tools). Registers are written as $0
, $1
, ..., $31
, and the destination register
goes on the left, followed by source registers and immediate values on the right. Most integer arguments (immediates,
shift amounts, jump targets) can be specified in hex (i.e. 0x12ab), in decimal (i.e. 1234 or -1234), a label, or the
special constant PC
. The assembler will replace PC
with the address of the instruction itself. Most
constants have some restrictions: jump destinations must have the same upper 4 bits as the PC+4
, and must be
a multiple of 4; branch destinations must be a multiple of 4 and fit in a signed 18 bit immediate; etc. As a special case, when a branch
target is specified symbolically as a label, the assembler will automatically subtract the current PC value to obtain
a signed offset.
By default, the first instruction will be placed at address 0, and subsequent instructions are placed at at addresses 4, 8, 12, etc.
Assembler directives. The Program ROM assembler understands two standard MIPS assembler directives, .text
and
.word
, both of which take integer (hex or decimal) arguments. For example, .text 0x50000000
will
direct the assembler to place subsequent instructions starting at address 0x50000000. And .word 0x24030005
directs the assembler to use the value 0x24030005 as the next machine instruction, which happens to be the machine
code for ADDIU $3, $0, 5
.
Some examples of instructions are:
Immediate Arithmetic | ADDIU $12, $0, PC |
Register Arithmetic | ADDU $13, $0, $20 |
Immediate Load | LUI $14, 0x123 |
Shifts | SLL $13, $13, 2 SLLV $15, $14, $3 |
Jumps | J 0x24 J my_label JR $5 JALR $31, $5 JALR $5 |
Branches | BEQ $5, $6, -12 BEQ $5, $6, my_loop_top BLEZ $9, 16 BLEZ $9, my_loop_done |
Memory Load/Store | LW $12, -4($30) SW $12, 0($30) |
Items in white are required for this and the next project. Make sure to decode all of them. The grayed out items are not implemented in either project, and you do not need to worry about them.
opcode | bits 28..26 → | ||||||||
↓ bits 31..29 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 | ||
0 | 000 | SPECIAL δ | REGIMM δ | J | JAL | BEQ | BNE | BLEZ | BGTZ |
1 | 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI |
2 | 010 | COP0 δ | COP1 δ | COP2 θδ | COP3 θδ | BEQL φ | BNEL φ | BLEZL φ | BGTZL Φ |
3 | 011 | β | β | β | β | SPECIAL2 δ | JALX ε | ε | * |
4 | 100 | LB | LH | LWL | LW | LBU | LHU | LWR | β |
5 | 101 | SB | SH | SWL | SW | β | β | SWR | CACHE |
6 | 110 | LL | LWC1 | LWC2 θ | PREF | β | LDC1 | LDC2 θ | β |
7 | 111 | SC | SWC1 | SWC2 θ | * | β | SDC1 | SDC2 θ | β |
function | bits 2..0 → | ||||||||
↓ bits 5..3 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 | ||
0 | 000 | SLL | MOVCI δ | SRL | SRA | SLLV | * | SRLV | SRAV |
1 | 001 | JR | JALR | MOVZ | MOVN | SYSCALL | BREAK | * | SYNC |
2 | 010 | MFHI | MTHI | MFLO | MTLO | β | * | β | β |
3 | 011 | MULT | MULTU | DIV | DIVU | β | β | β | β |
4 | 100 | ADD | ADDU | SUB | SUBU | AND | OR | XOR | NOR |
5 | 101 | * | * | SLT | SLTU | β | β | β | β |
6 | 110 | TGE | TGEU | TLT | TLTU | TEQ | * | TNE | * |
7 | 111 | β | * | β | β | β | * | β | β |
rt | bits 18..16 → | ||||||||
↓ bits 20..19 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |
000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 | ||
0 | 00 | BLTZ | BGEZ | BLTZL | BGEZL | * | * | * | * |
1 | 01 | TGEI | TGEIU | TLTI | TLTIU | TEQI | * | TNEI | * |
2 | 10 | BLTZAL | BGETAL | BLTZALL | BGETALL | * | * | * | * |
3 | 11 | * | * | * | * | * | * | * | * |