Proj2 Details
t
Project 2 Details
Check out the ISA here. (https://canvas.pitt.edu/courses/294985/pages/proj2-isa)
You may use any built-in Logisim component to build your CPU! You don’t have to build the ALU
out of 500 gates or the registers out of flip flops. Explore the stuff in the component pane... many,
many things are done for you!
You may also use anything you’ve made in the labs. lab8 will definitely be useful...
Just don’t use any circuits someone else made, because that’s cheating, duh.
Here are the main parts of the CPU, ordered vaguely by increasing difficulty:
1. The program ROM and data RAM
2. The display unit and Halt LED
3. The ALU
4. The register file
5. The PC FSM
6. Now What?
7. The control
8. The interconnect
9. Branches
1. The program ROM and data RAM
On your main circuit, place a Memory > ROM component with these settings:
Address Bit Width: 8
Data Bit Width: 22
That will give you 256 22-bit instructions.
The ROM is super simple to use: put instruction address (i.e. the value of the PC register) into the
left side, get instructions out the right side.
Then place a Memory > RAM component with these settings:
Address Bit Width: 16
Data Bit Width: 16
Data Interface: Separate load and store ports (this is important)
This will give you 65536 words of RAM.
4/20/25, 9:09 PMProj2 Details: 2254 CS 0447 SEC1090 COMPUTR ORGZTN & ASSMBLY LANG
https://canvas.pitt.edu/courses/294985/pages/proj2-details1/9
The address and data to store go in the left side, the clock in the bottom (the triangle), and the
data to load comes out the right side.
The str input is the memory’s write enable signal. Most instructions don’t write to the memory, so
you’ll have to hook something up to it.
You can ignore the sel, ld, and clr inputs!
And that’s it for those... for now!
2. The display unit and Halt LED
On your main circuit, place four Input/Output > Hex Digit Display components next to each
other. If you change the colors, please make sure it’s easy to read!
Now, to control those, make a display unit component like this:
INPUTS:
1-bit Clock
(that means this is a sequential circuit - it’ll have a register inside!)
1-bit Write Enable
16-bit Data
OUTPUTS:
4 x 4-bit Digit values (e.g. Digit0 through Digit3)
do not put the digit displays inside this component!
BEHAVIOR:
It holds a 16-bit value in a register
It outputs that stored 16-bit value, split into groups of 4 bits
Bits 0-3 are the rightmost digit
Bits 12-15 are the leftmost digit
The Write Enable input is the register’s write enable.
You can test this component without any other circuitry built. Plop down the display component,
wire it up to the digits, and put some inputs next to it. Poke the inputs, clock it, see if it works.
4/20/25, 9:09 PMProj2 Details: 2254 CS 0447 SEC1090 COMPUTR ORGZTN & ASSMBLY LANG
https://canvas.pitt.edu/courses/294985/pages/proj2-details2/9
In the above test, I put 0x1234 into the display and it’s displaying 1234. If yours shows 4321 with
the above input data, you have the digits hooked up backwards ;)
Once you’re satisfied that your display is working, delete the temporary inputs. They were just for
testing, and you can get rid of them now. They’ll be connected to other things later.
Finally, place an Input/Output > LED next to the digit displays, and label it HALT. Nothing will
connect to it yet, but it should be clearly labeled and visible close to the digits.
3. The ALU
The ALU is a combinational circuit. Remember, you’re allowed to use any of the built-in
Logisim components - adders, subtractors, shifters, bit extenders etc.
The ALU is very similar to what you made in lab 8. If you finished that lab, you can copy the
circuitry out of that and modify it slightly by changing things to 16 bits instead of 8.
The ALU component works like this:
INPUTS:
4/20/25, 9:09 PMProj2 Details: 2254 CS 0447 SEC1090 COMPUTR ORGZTN & ASSMBLY LANG
https://canvas.pitt.edu/courses/294985/pages/proj2-details3/9
16-bit A
16-bit B
3-bit Operation
OUTPUTS:
16-bit Result
BEHAVIOR:
The Result output depends on what Operation is chosen:
if Operation = 000, then output A + B
if Operation = 001, then output A - B
if Operation = 010, then output A & B
if Operation = 011, then output A | B
if Operation = 100, then output A ^ B (that’s XOR)
if Operation = 101, then output ~B (A is ignored)
if Operation = 110, then output A << B[3:0] (see below)
if Operation = 111, then output A >>> B[3:0] (logical, not arithmetic)
Notes:
the syntax B[3:0] means “bits 3, 2, 1, and 0 of B”. It’s commonly used in hardware design.
So, you can use a splitter with a fan-out of 1, or a Bit Extender in this particular case.
AND, OR, XOR, and NOT gates also have a “Data Bits” property.
Test it out thoroughly!!! It’s so easy to accidentally connect things to the wrong places. Make sure
it does what you expect for every operation. You can just poke the inputs inside the ALU circuit to
test it. Remember that probes are your debugging prints; they are not outputs, but they can
be helpful to see what values are being produced.
4. The register file
Again, this register file is almost exactly the same as what you made in lab 8, but 16-bit
instead of 8-bit.
I showed how to make the register file in class, and you presumably did it on the lab too. Details:
1 write port (rd to select the register, REG[rd] is the data input)
2 read ports (rs and rt to select the registers, REG[rs] and REG[rt] are the data outputs)
one write enable input
one clock input
8 registers, 16 bits per register
but register 0 is not a register - just a constant 0
Test it out thoroughly!!! Do this for every component you make, ok?
5. The PC FSM
4/20/25, 9:09 PMProj2 Details: 2254 CS 0447 SEC1090 COMPUTR ORGZTN & ASSMBLY LANG
https://canvas.pitt.edu/courses/294985/pages/proj2-details4/9
The PC is a register which holds the address of the current instruction. Since your instruction
memory uses 8-bit addresses, what size should the PC register be?
Remember from class that the PC can move ahead by 1 instruction, or jump to other places, or
conditionally branch. That’s what this component is for.There is also an example PC FSM on
the Materials page whose structure you can base yours on
(https://jarrettbillingsley.github.io/teaching/classes/cs0447/materials.html) . Don’t just copy and
paste the circuitry; try to replicate it yourself.
It will have:
INPUTS:
1-bit Clock
16-bit Offset (16 bits for convenience on the main circuit)
16-bit Target (ditto)
1-bit Jump
1-bit Branch
1-bit Halt
OUTPUTS:
8-bit PC Out
16-bit PC+1 Out (16 bits for convenience on the main circuit)
BEHAVIOR:
If Halt is 1, the PC register is disabled.
If Jump is 1, PC will be set to Target[7:0] (you can use a bit extender to get the 8 low
bits).
Else if Branch is 1, PC will be set to PC + Offset[7:0].
Else, PC will be set to PC + 1.
PC+1 Out should output whatever comes out of the adder, zero-extended to 16 bits.
Like we said in class, how the branch conditions are checked are not really the responsibility of
this component! That is explained later and done elsewhere.
6. Now What?
From here, things get a little weird. You have two more important things to make: the
interconnect (connecting all the components together) and the control (tells all the components
and the interconnect what to do for each instruction).
However, you can’t really make one without knowing something about the other. It’s technically
possible to do all the interconnect before moving onto the control, but most people aren’t familiar
enough with how the CPU works yet to be able to do that easily!
Since the project is graded using these test programs
(https://canvas.pitt.edu/courses/294985/files/20158215?wrap=1)
(https://canvas.pitt.edu/courses/294985/files/20158215/download?download_frd=1) , you should
4/20/25, 9:09 PMProj2 Details: 2254 CS 0447 SEC1090 COMPUTR ORGZTN & ASSMBLY LANG
https://canvas.pitt.edu/courses/294985/pages/proj2-details5/9
probably have that page open so you have an idea of what to work on, and in what order. The
tests are ordered in increasing difficulty.
You should also keep the ISA page open (proj2-isa) , since the ISA really tells you everything you
need to know for the interconnect and control. The instructions are in (mostly) the same order as
the test programs that test them.
Last, this tutorial (proj2-tutorial) should help you get started on the control and interconnect. After
you do the first few instructions, you’ll be able to do the rest much more easily.
7. The control
The control is the biggest and most complex component. It is going to have a lot of outputs!
Its one and only input is the instruction that comes out of the ROM. It does not have a clock
input as it is a combinational circuit.
It will output a few categories of things:
The register indices (rd, rs, and rt) extracted from the instruction
The immediate, which has been appropriately zero- or sign-extended (explained below)
All the control signals for every other component and the interconnect
Please go look at the Control lecture slides. There is also a decoding.circ example on the
Materials page that shows many of the concepts in practice, but for a small subset of MIPS, not
this project’s ISA.
To summarize those slides and example, there are three main stages to making the control:
1. Split up the instruction.
Use splitters to split the instruction into its fields.
Fortunately, you only have one instruction format to deal with this term.
It’s documented on the ISA page (proj2-isa) .
After splitting you should have:
the opcode (5 bits)
rd, rs, and rt (all 3 bits, and they just go right out of the control)
and an 8-bit imm (but see the section below...)
2. Decode the opcode.
5-bit opcode into a 5-bit decoder. boom.
Look at the ISA (proj2-isa) to see which opcodes correspond to which instructions. It lists
them all in numerical order.
Name the tunnels coming out of the decoder like so: hlt, put, li, lui, etc.
Don’t waste space naming them put rs or whatever!
And definitely DO NOT name them 00000, 00001, etc. YOU ARE NOT A COMPUTER!!
Keep the opcode and its decoded versions inside the control unit. Don’t send the opcode
all over the CPU and decode it elsewhere!
4/20/25, 9:09 PMProj2 Details: 2254 CS 0447 SEC1090 COMPUTR ORGZTN & ASSMBLY LANG
https://canvas.pitt.edu/courses/294985/pages/proj2-details6/9
3. Come up with the control signals.
Make one output for each control signal you need to produce.
Again, like on the slides: after you’ve decoded the opcode, it’s just a matter of coming up
with circuits for each of those outputs, based on what the opcode is.
Some example control signals are:
Halt, which halts the PC FSM
RegWE, the write enable for the register file
MemWE, the write enable for the RAM
DispWE, the write enable for the display unit
ALUOp, the operation the ALU should perform
RegDataSrc, the selector for the MUX on the input of the register file
and so on...
Dealing with the immediates
Some instructions use a sign-extended version of imm (written sxt(imm) in the ISA), and some
use a zero-extended version of imm (written zxt(imm)).
Rather than doing the extension elsewhere, I have my control deal with it and just output a 16-
bit “imm” value which is either sign- or zero-extended based on the instruction. Here’s an idea:
on the ISA page, find all the instructions that use zxt(imm). (Use ctrl/cmd+F in your
browser)
OR those instruction signals together. that gives you a signal that’s 1 for zero-extension and 0
for sign-extension.
use that to control a MUX to choose which version of the immediate to output from the control.
8. The Interconnect
Now you can go on the main circuit, and plop down one of each of your components you made.
That’s one each of:
The RAM (you put that already)
The ROM (you put that already)
The Display unit (you put that already)
The Register File
The ALU
The PC FSM
The Control
Here are the broad strokes:
The clock signal is needed by several components:
The RAM
The Display unit
4/20/25, 9:09 PMProj2 Details: 2254 CS 0447 SEC1090 COMPUTR ORGZTN & ASSMBLY LANG
https://canvas.pitt.edu/courses/294985/pages/proj2-details7/9
The Register File
The PC FSM
The PC FSM’s PC Out output goes into the ROM’s A input.
The ROM’s D output goes into the Control’s instruction input.
The Control’s rd, rs, rt outputs go to the register file.
Some more tips:
Use tunnels. Tunnels will let you name your wires and move the parts of your CPU around
independently.
Copy and paste your tunnels. This will avoid naming mistakes (e.g. naming one end PC and the
other end pc, which are different names).
Every time you put a MUX down, make a tunnel for its select signal and name it like “___Src”, e.g.
“RegSrc” or “ALUBSrc”. You can also use the tunnel colors to make the control signals stand out
(like coloring them blue). For example, here’s a tiny piece of mine:
Here I used red for registers, orange for the ALU, dark blue for the immediate, and light blue for
control signals.
9. Branches
The branch instructions often give people trouble. Often people find it easier to implement the
conditional branch logic later in the project, after they’ve made some interconnect/control
logic. So, maybe come back to this section once you get to those tests.
Here are some common questions and answers:
How do I check the branch condition?
Branch conditions are comparisons.
So, you could use a Comparator... or you could use your ALU, set to do a subtraction.
The latter is “more realistic” if that matters to you ;)
You will still have to use a Comparator component to compare the ALU output to a
constant 0.
Just be sure that no matter how you do it, you set that comparator to use “2’s
complement” comparison!
Where do I check the branch condition? In the control? The PC FSM? The ALU?
4/20/25, 9:09 PMProj2 Details: 2254 CS 0447 SEC1090 COMPUTR ORGZTN & ASSMBLY LANG
https://canvas.pitt.edu/courses/294985/pages/proj2-details8/9
Definitely not in the control. Bad place for it!
You could check the condition on the main circuit. The needed values are right there
already.
You could do it in the PC FSM too, but that might mean adding several more inputs to it,
which might be ugly...
What control signals do I need to do this...?
Well, you need to know whether or not the current instruction is a branch, and then
also which branch condition it is.
This can be done in as few as 2 signals (one 1-bit, one 2-bit) or as many as 5 (all 1-bit).
My branches are ALWAYS (or NEVER) branching!
The branch should happen only when:
The current instruction is a branch, AND (as in, use an AND gate lol) the branch’s
condition is satisfied.
It’s easy to only check for one of these and forget to check the other.
4/20/25, 9:09 PMProj2 Details: 2254 CS 0447 SEC1090 COMPUTR ORGZTN & ASSMBLY LANG
https://canvas.pitt.edu/courses/294985/pages/proj2-details9/9