COMP311: Lab 3

Pull the new starter code!

The starter code for each subsequent lab will be added directly into the same course repository. To update your individual repo, navigate to your workspace on the GitHub website and you should see a “Sync Fork” button. Click this and then “Update Branch.” Now if you run ``git pull’’ in your terminal, you will have all the materials you need.

OR

If you went through the additional git set-up steps for lab 1, you should be able to run

git pull starter main --rebase

Then all the new code for lab3 should be there!

ALU

In this lab, you will be the designing the 32-bit ALU we have been studying in class up to this point! Note, we will have to make some modifications to match the 32-bit RISC-V instructions we will introduce soon, but this is a good start. :)

You will start by designing the three sub-units. Then, you will bring them all together to create a functional ALU!

Exercise 1: Boolean Unit

We will begin by building our Boolean Unit!

Deliverable: boolean-unit.dig

Implement your 32-bit Boolean unit based on the specification provided in the table above.

boolean-unit.dig already has the named inputs and outputs that your circuit must use. DO NOT change the names of the inputs and outputs.

Components

Testing

A local tester for the Boolean Unit is provided. This video explains how the tester works.

Common Error

Exercise 2: Bidirectional Shifter

Time to build our Bidirectional Shifter!

Deliverable: bidirectional-shifter.dig

Implement your 32-bit Shifter Unit based on the specification provided in the table above.

bidirectional-shifter.dig already has the named inputs and outputs that your circuit must use.

Component: Barrel Shifter

You will be use a component called Barrel shifter which can be found in Components → Arithmetic → Barrel shifter.

Inputs

Types of Shift Operations

A single barrel shifter can only perform one type of shift, so you will need three barrel shifters in your design: one will perform an arithmetic right shift, one will perform a logical right shift, and one will perform a left shift.

To choose the type of shift, right click on the barrel shifter and alter the Direction and Mode:

Tips

Testing

A local bidirectional shifter unit tester is provided. The tester works the same as it did for the Boolean Unit.

The tester expects that if Bool = 0b01, the output will be 0 (as shown in the diagram at the top of this section). You can either use the ground component or a constant to set the output to 0. Remember to update the bit width of these components.

Exercise 3: Add/Sub Unit

Onto our third sub-unit the Add/Sub unit!

Deliverable: add-sub.dig

Your completed add/sub unit should output: - The result of your arithmetic operation - The Sign of your result - Whether or not Overflow has occurred

The new outputs Sign and Overflow are explained below.

add-sub.dig already has the named inputs and outputs that your circuit must use.

Addition

You will use the Adder component to implement addition. Make sure you update the bit width of the adder.

Subtraction

Digital also has a component named Subtract, however you are NOT allowed to use it. Doing so will fail the autograder.

To implement subtraction, you will use the same method we studied in class: to perform the operation A - B, you negate B and then add it to A.

Sign

Sign is a one bit output that indicates the sign of our result. If Sign is 1, the result is negative. If Sign is 0, the result is positive.

Sign of Out Value of Sign
positive 0
negative 1

Overflow

Overflow is a one-bit output that will indicate if the operation overflowed. If Overflow is 1, overflow occurred. If Overflow is 0, overflow did not occur.

How do we know if overflow occurred? Recall the following information from COMP 211:

Operation Overflow occurs when
Adding two positive numbers The result is negative
Adding two negative numbers The result is positive
Adding two numbers of opposite signs Overflow will never occur

Adding two positive values should yield a positive result, so if the result is negative, this indicates that overflow has occurred. Adding two negative values should yield a negative result, so if the result is positive, this indicates that overflow has occurred. When adding numbers with opposite signs, overflow is not possible, as the sum always remains within the representable range of values for the given number of bits.

Ok, so we know how to detect overflow for additions. What about subtractions? Well, the circuit we built only performs addition (to perform subtraction, we negate B and add it to A), so we only need to know how to detect overflow when performing addition.

To implement the circuit that will detect overflow, start by filling out the table below. Then generate your equation and build your circuit!

Sign of A Sign of B Sign of Result Overflow?
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

Testing

A local add-sub unit tester is provided. It works the same as the testers for the previous components.

We recommend that you test incrementally. Implement the features in the order provided below. Test each feature before moving onto the next one. Following this process will save you a lot of headaches!

This video provides guidance on testing your add-sub unit incrementally.

  1. Implement addition. Verify that your circuit produces the currect Out value. Ignore Sign and Overflow for now.
  2. Implement subtraction. Verify that your circuit produces Out value for both addition and subtraction. Ignore Sign and Overflow for now.
  3. Implement and test Sign.
  4. Implement and test Overflow.

Exercise 4: Comparator Unit

We would like our ALU to perform the operation A < B. If the input A is less than B, the result will be 1. If A is greater than or equal to B, the result will be 0. We will design a new unit called Comparator to perform this operation!

Deliverable: comparator.dig

Implement the Comparator Unit as specified above.

comparator.dig already has the named inputs and outputs that your circuit must use.

Method

To determine if A is less than B, we subtract B from A and analyze the result. Specifically, if A−B yields a negative result, this indicates A is less than B. Conversely, a positive result implies A is greater than or equal to B.

When we want to perform A < B, we’ll set the control signal Sub to 1 to perform A-B. The outputs from the add/sub unit you designed earlier, Sign and Overflow, will serve as inputs to our comparator.

Now, you might be thinking, “can’t I just look at Sign to know if A is less than B?” That would be fine except in the case where A - B overflows. If A-B overflows, and Sign is 0, then A is less than B, and if Sign is 1, then A is not less than B. This bevahior is summarized in the table below.

Overflow Sign A < B?
0 0 0
0 1 1
1 0 1
1 1 0

Using the table, generate the Boolean equation for detecting overflow and then implement your compator circuit.

Testing

A local comparator unit tester is provided. It works the same as the testers for the previous components.

Exercise 5: ALU

It is now time to start building our ALU! Here is the full implementation of our ALU with the comparator unit included:

Deliverable: alu.dig

The schematic provided in alu.dig already has the named inputs and outputs that your circuit must use.

The ALU unit should be able to: - Perform the following operations - addition - subtraction - A < B (this operation is known as set on less than or SLT) - left shift - logical right shift - arithmetic right shift - bitwise AND - bitwise OR - bitwise XOR - bitwise NOR - Output if the result is zero on FlagZ.

Building your ALU

To add a custom component, navigate to Components → Custom → “component-name”. Add your Add-Sub Unit, Bidirectional Shifter, Boolean Unit, and Comparator.

Now it’s time to wire everything up! Please save yourself a huge headache and use tunnels.

Comparator

The comparator produces a 1-bit output. The result of the ALU is 32 bits. To make the bit widths compatible, you will need to zero-extend the output of the comparator to be 32-bits. You can do this with the splitter/merger component.

If the ALU is performing the operation A < B: - If A is less than B, Result = 0x00000001 - If A is not less than B, Result = 0x00000000

FlagZ

FlagZ, known as the Zero Flag, checks if the result of our ALU is 0. If the result is zero, FlagZ is 1, otherwise FlagZ is 0. You can find the comparator in Components → Arithmetic → Comparator:

It is important to note that this component may NOT be used when computing A < B. This will result in the failing of the autograder.

Make sure you set the data bits of the comparator to 32!!!

Testing

A local ALU unit tester is provided. It works the same as the testers for the previous components.

Submission Instructions

Assignments are submitted through Gradescope.

  1. Commit and push your changes to your Lab 3 GitHub repo.
  2. Go to the COMP 311 course in Gradescope and click on the assignment called Lab 3.
  3. Click on the option to Submit Assignment and choose GitHub as the submission method. You may be prompted to sign in to your GitHub account to grant access to Gradescope. When this occurs, grant access to the Comp311 organization.
  4. You should see a list of your repositories. Select your 311 workspace.
  5. Your assignment should be autograded within a few seconds and you will receive feedback.
  6. If you receive all the points, then you have completed this lab assignment! Otherwise, you are free to keep pushing commits to your GitHub repository and submit for regrading up until the deadline of the lab.