CIS 351

Project 4

Fall 2021

GitHub Classroom link to the starter code. Make sure you have the latest version of DLUnit. You can download it here.

For this project, you will use JLS to build the Single Cycle CPU described in Chapter 7 of the Harris and Harris textbook (Chapter 4 in the Patterson and Hennessy textbook).

You will complete this project in two phases:

It is critically important that you thoroughly test Phase 1 before moving onto Phase 2. Every team that did not do this last semester had serious problems completing this project. Find me immediately if you have any trouble getting the testing software to work. If you don't have the testing software working, you really have no idea whether your CPU is functioning correctly.

Be sure to read this entire document (especially the hints) before you begin. Overlooking any of the instructions or hints can lead you down a dead-end path that will waste hours of your valuable time.

Pre-requisites

You will need to understand

Phase 1

Build the Single-Cycle CPU shown in in Figure 7.14. To help you get started, the starter code contains StarterCPU_f21.jls which includes a

Before you begin, rename the starter CPU file PHSingleCycleCPU.jls. You aren't required to use the provided components; but, building your own can be tedious. The purpose of the "starter" control unit is so that you can debug your CPU's datapath separately from the control unit. Once you have the core instructions working, then replace my control unit with one you build from scratch. (This is phase 2)

Interface

At the end of Phase 1, your CPU should support the following instructions:

Name Mnemonic Format OpCode
(in hex)
Func Code
(in hex)
Add add R 0 20
Add Immediate addi I 8
And and R 0 24
And Immediate andi I c
Branch if Equal beq I 4
Halt halt   20
Jump j J 2
Load Word lw I 23
Load Upper Immediate lui I F
Nor nor R 0 27
Or or R 0 25
Or Immediate ori I d
Set Less Than slt R 0 2a
Set Less Than Immediate slti I a
Store Word sw I 2b
Subtract sub R 0 22

Phase 1 Testing

In order for your CPU to work seamlessly with the test suite, it must use the following interface:

DLUnit has a built-in test class that can test this CPU. In addition to the .jls file, you also provide an assembly file as input. DLUnit will (1) simulate the assembly code using MARS, (2) simulate the assembly code using your CPU, then (3) compare the final state of the registers from each simulation. The test will pass if your CPU ends in the same state as the CPU simulated by MARS.

IMPORTANT: DLUnit only checks the final state of the CPU. If you write to a register more than once, the intermediate values of that register won't get checked.

The syntax for running DLUnit to test a CPU is java -jar DLUnit.jar jls_file.jls builtin.SingleCycleCPUTest --param assembly_file.a To test your code, you will need to write several example assembly programs. The starter code includes a few example testing programs; however, these programs alone won't test your CPU well.

Avoid the following cases when writing your phase 1 tests:

To run the Phase 1 tests, click on the "Actions" tab on your project's GitHub page, then select "Part 1 Workflow"

Debugging

The best way to debug a circuit that is failing tests is to use JLS to step through each instruction. The starter code includes a bash script named marsAssembler that takes an assembly file as input and generates machine code. To debug your circuit, run marsAssembler and redirect its output to a file named instructions. Your circuit's Instruction Memory element is configured to load data from this file. So, if you launch JLS in a directory containing instructions you will be able to step through your CPU instruction by instruction. Important: marsAssembler is a bash script. It won't run on the Windows command line. You will need to use Cygwin, WSL, or something similar to run it. Another option is to look inside the bash script and just run the Windows version of that command "by hand".

Note: marsAssembler only works with DLUnit version 1.1.1 or newer (built 3 November 2020). You may need to download the most recent version (linked here). Also, make sure marsAssembler and DLUnit.jar are in the same directory.

Phase 1 Hints

Phase 2

You have three main tasks to complete for Phase 2:

  1. Replace my "starter control" with your own hard-wired control.
  2. Add additional instructions.
  3. Determine the critical path for the CPU and set the clock accordingly.

Hard-Wired Control

Remove the starter control and replace it with your own control unit. The starter control is a type of microcode. You are going to build a hard-wired control. You must

*Some control wires have very similar truth tables (e.g., ALUsrc and RegDest). Groups with similar truth tables may share components. You need not generate a separate truth table and Karnaugh map in this case.

When you implement your control unit, plan ahead an include the additional instructions (listed below).

Additional Instructions

Add support for these additional instructions. (Remember to consider them as you implement your control unit.)

Name Mnemonic Format OpCode
(in hex)
Func Code
(in hex)
Add Unsigned addu R 0 21
Add Immediate Unsigned addi I 9
Branch if not Equal bne I 5
Jump and Link jal J 3
Jump Register jr R 0 08
Set Less Than Unsigned sltu R 0 2b
Set Less Than Immediate Unsigned sltiu I b
Subtract Unsigned sub R 0 23
Xor xor R 0 26
Xor Immediate xori I e

Phase 2 Hints

To run the Phase 2 tests, click on the "Actions" tab on your project's GitHub page, then select "Part 2 Workflow"

Submission and grading

In order to get an 'M' or 'E' for this project, you must have

To submit your project:

  1. Make sure all .jls files include a comment with your name.
  2. Make sure PHSingleCycleCPU.jls includes a comment with the clock period.
  3. Make sure your repository includes all your test files / test plans.
  4. Add a commit message with [Grade Me] and push.

Updated Thursday, 21 October 2021, 7:44 PM

W3c Validation