Your task

You will be building two components, following what we talked about in lecture:

  1. An ALU capable of doing operations on 8-bit inputs
  2. An 8-bit register file with 8 registers (well, 7, plus a zero register)

0. Starting point

Save this file, rename it with your username, and open it in Logisim.

You cannot double-click abc123_lab7.circ to open it in Logisim. You have to run Logisim and use File > Open to open it.

When you open it you will see this:

a screenshot of the circuit as it looks when you first open it

At the top-left is the clock thing that you should now be familiar with.

The top section is for the ALU; the bottom section is for the register file. (Okay looking at it now, it’d make more sense to put the clock in the bottom section but WHATEVER.) On the left side are all the inputs you’ll use to control the components, and in the middle are some probes to show some important values.

On the right is where you will place your ALU and register file components, once you have made them. The tunnels carrying inputs to those components are on the left, and the tunnels that will carry the outputs are on the right. (That’s why some probes show XX, because no value is being produced yet.)

Like it says on the circuit, don’t move or reorder those tunnels. Your ALU and register file components should work by simply placing them between the tunnels. This is for autograding purposes.

1. Making the ALU

  1. Make a new subcircuit with Project > Add Circuit… and name it ALU exactly (blah blah autograding)
  2. Let’s place all the inputs and outputs first, kind of like how when we write a function, we write the arguments and return type first. Your ALU needs these inputs and outputs:
    • A and B inputs, both 8 bits; these are the values to operate on.
    • an ALU Op input, 3 bits; this is the operation to perform.
    • an ALU Out output, 8 bits; this is value that you get from performing that operation.
      • (we’re ignoring overflow for this simple ALU.)
  3. Make corresponding tunnels for each input and output. Name them the same as the inputs and outputs.

Do NOT use Wiring > Pin, ever. Use the input and output tools at the top of Logisim. These 👉👉👉 Square is input, circle is output. Okay? Good.

Making the ALU Do the Thing

As explained in class, a simple way to make an ALU is as a MUX, where the select signal chooses the operation.

  1. Make a MUX with 8 data bits and 3 select bits. The ALU Op will be the select input (the one on the angled side) and the output of the MUX will be the ALU Out.
  2. Finally, we can make the parts that do stuff. These are the operations the ALU should perform based on ALU Op:
    • ALUOp = 000: A + B
    • ALUOp = 001: A - B (use an Arithmetic > Subtractor for this, don’t worry about doing it like lab 5)
    • ALUOp = 010: A & B (remember you can set a gate’s “Data Bits” too)
    • ALUOp = 011: A | B
    • ALUOp = 100: A ^ B (that’s XOR)
    • ALUOp = 101: ~B (that’s NOT; A is unused in this operation!)
    • ALUOp = 110: A << B[2:0] (that’s an Arithmetic > Shifter with “Logical Left” shift type; also see below)
    • ALUOp = 111: A >>> B[2:0] (use “Logical Right” for the shift type)

The syntax B[2:0] means “the least significant 3 bits of B”. The easiest way to do this is to use a Wiring > Bit Extender, which despite its name, can also truncate larger values to smaller ones. Just set its input bits to 8 and output to 3. (It’s also possible to truncate using a splitter with a fan-out of 1, if you’re a fan of splitters.)

Why is the second input of the shifter component only 3 bits instead of 8? Well, think about it this way: if you have an 8-bit number, what’s the furthest you can possibly shift it in either direction? At most 7 bits. How many bits do you need to represent a distance of 0 to 7? Just 3 bits.

2. Placing and testing the ALU

Once you have all the operations built, you can go back to the main circuit. Single-click on the ALU’s name on the left, and then you can place it onto the main circuit. There should be 3 pins on the left (for the inputs) and 1 on the right (for the output), like the image to the right.

If the pins (dots) are all on one side of the component, it’s because Logisim is very sensitive to the direction you have the input/output components facing in the component’s circuit. Inside the ALU component, select the ALU Out output and use the arrow keys on your keyboard to make it face the opposite direction. Now it should be on the right side of the box in the main circuit. This is why the output tool in the toolbar orients them that way when you first place them.

To be clear, this is what I mean about the directions of the inputs and outputs:

2.1 Are the inputs in the right order?

Remember, you aren’t allowed to move/reorder the tunnels on the main circuit. So the inputs on the left side have to be in the right order.

Put your mouse cursor over an input and you will see a green circle; then after a second, it will show the name of that pin. See the image to the right for what I mean.

From top to bottom, the inputs on the left side must be:

If you get this message when you hover over a pin, then edit the ALU, click on the input/output components, and make sure their “Label” property is set. That is what is used to show you the pin label when you hover over it on the main circuit.

Attaching a tunnel to an input or output does not name it. You must set its “Label” property.

2.2 Testing the ALU

Finally, on the main circuit, drag the ALU in between the provided tunnels to hook up the inputs and outputs so it looks like the image to the right.

Now you can test it. For example, let’s test addition:

If there is a problem (e.g. a blue or red wire coming out of the ALU), see the section below. Otherwise, keep testing. Test all 8 operations to ensure they do what they should. These are the values for ALUOp and what they do.

Once you are satisfied all 8 operations are working correctly, you can move onto the register file.

Looking inside components

Let’s say you’re testing the ALU and you start getting a red or blue wire coming out of it. “Okay,” you say, “let’s look inside the ALU.” So you double-click its name on the left and…

Where’s the error? It looks fine. What? What’s going on?

See, when you double-click a circuit on the left side, what you are editing is kind of the “original template” of the circuit. You can think of it kind of like editing a class in Java.

But when you place that component in the main circuit, it makes an instance or copy of it, like using new in Java. And just like in Java, every time you make a new instance of the ALU, it has its own inputs, outputs, mux, adder, etc. etc. etc.

So to see where the red wire is coming from, you have to look inside the instance.

  1. use the hand tool
  2. click on the ALU component; a magnifying glass will appear
  3. double click the magnifying glass

Now you are looking inside the ALU instance. There is a message at the top of the screen (“You are viewing the state of an embedded subcircuit.”) to indicate this, and the background is also a yellowish color.

There’s the error! Now you can diagnose where the problem is coming from.

To go back to main, you can either:

3. Making the Register File

Hey. Hey. The register file you are making is not exactly the same as what’s on the slides. Please read the following paragraph. Thank you.

The register file is very similar to what was shown in class, but instead of 3 registers + a fake 0 register, it will have 7 registers + a fake 0 register. Also, the registers and the data input/outputs will all be 8 bits, not 32.

Time to repeat the process:

  1. Project > Add Circuit…, name it Register File exactly.
  2. Add its inputs and outputs like you did with the ALU.
    • Inputs (note that this is the order they appear on the main circuit)
      • CLK - 1-bit clock signal (this is an input, not a clock component)
      • REG[rd] - 8-bit value to be written to rd if Reg WE is 1
      • Reg WE - 1-bit write enable input; enables writing to the rd register
      • rd - 3-bit number of register to be written to, if Reg WE is 1 (goes with REG[rd])
      • rs - 3-bit number of the first register to read from (goes with REG[rs])
      • rt - 3-bit number of the second register to read from (goes with REG[rt])
    • Outputs
      • REG[rs] - 8-bit output of first register (selected by rs)
      • REG[rt] - 8-bit output of second register (selected by rt)

Now, using the circuitry provided on the slides as a template, you’ll build the register file yourself. Important notes:

Test your register file by poking the inputs some more. Here are some tests you can try (don’t reset between tests!):

Finally, place it on the main circuit and test that it works when hooked up to the tunnels, too. (If you put your inputs in the wrong order in the Register File circuit, you might get orange wires and “Incompatible Width” errors.) Just remember that if you want to look at the values in the actual registers, use the hand tool to click on the component in the circuit, then double-click the magnifying glass.

By the way, the little semicircle at the top of the rectangle is not the clock input. It’s a decoration meant to be the little “orientation notch” that is seen on real chips to indicate which end is which. Like this. Awww. It’s cute.


Once you’re sure your circuit works, you can submit.

To submit:

  1. On Canvas, go to “Assignments” and click this lab.
  2. Click “Start Assignment.”
  3. Under “File Upload,” click the “Browse” button and choose your .circ file.
  4. Click “Submit Assignment.”

If you need to resubmit, that’s fine, just click “New Attempt” on the assignment page and upload it again.