# Designing a Control Unit

I have recently began studying processors and am attempting to design my own simple processor in Logisim. I have previously studied the MIPS Assembly Language and am hoping to have my processor work on instructions similar to MIPS. My instructions are 12-bits in length and my ALU only supports addition and subtraction. My CPU uses a 12-bit instruction RAM and an 8-bit data RAM.

My instruction set so far will only consist of the following 4-bit opcodes, similar to MIPS instructions:

lw    0000
sw    0001
sub   0100


My instructions are of the following format:

     [opcode: 4 bits] [rs: 2 bits] [rt: 2 bits] [rd/offset/const: 4 bits]


For example:

addi $t1,$1, 5    ->    0010 1010 0101


I have created the program counter, ALU, 8-bit register, etc. but the one bit I am really lost with is the control unit. I understand that the control unit should take as input the opcode of the instruction, and then output signals to the necessary registers / memories / ALU / etc.

So, how many outputs will my control unit need and what will each output correspond to?

You will almost certainly need more than one line for the ALU OP. (I doubt that all operations will be ADD or SUB. For example, NOP might be needed.) You mention four, but I see five written there. I think you will be quickly needing instructions to allow multi-precision add and subtract, as well.

You haven't specified how you will arrange your CPU but you will also almost certainly need a line for a latch prior to one of the two inputs to the ALU, if you share a common bus on that side. That line latches a value long enough for you to retrieve a second value and place it onto the bus. You might want a latch for both ALU inputs. If so, that's two lines instead of one.

If you support ADD with carry and SUB with borrow, then you will need two more control lines to allow the Carry-in to be one of four values: 0, 1, $\overline{C}$, or $C$.

ALU status will need to be captured with another latch -- and its associated control line. If you want to read this ALU status register as data, you'll need a separate latch with a tri-stating control for that. Two more control lines.

You almost certainly will need a latch at the output of the ALU to capture the output after enough time has passed for the combinatorial delay. This latch almost certainly will require a tri-stating input, as well, so that the bus can be shared with your register file, fetched memory values, etc. So that's two lines to this latch.

You say you've achieved some things (like RAM) but haven't said anything about how. So I assume you know the control lines required there. But you will need a program counter (a latch), a way to increment it, and a way to load it, and a way to clear it or set it upon reset. But you will need control lines for these operations.

Your PC register (used for accessing the next instruction) will probably need a prior mux, as well, to get access to registers and/or its adder system. This is distinct from the address bus latch and will require more control lines for the mux.

Outgoing bus values will need a latch to hold the value for the memory bus. That's another one or two control lines (latching and tri-stating output if the external data bus is bi-directional.)

You need a register to hold the current instruction (and possibly the next one, too, depending on how you are managing things.) This register needs to be latched from the incoming data bus at the right time. Another control line for that.

If you have addressing modes (and you have an addi and an add, so you do already), you will need a mux (more lines) and fixed registers to tap into (more lines), in order to support your address latch and separate adder -- oh, that separate adder requires more control lines, too.

You probably will need another mux to reach your external bus address latch, as well. You will at least want to be able to select the output of your addressing adder or alternatively, some register file output. So that's at least one more control line if not more for that mux, too.

Do you have a stack pointer? More control lines. Register file? Still more lines.

You may need special constants -- like 0, -1, 1, 2, and others. And you'll need a mux for that and more control lines.

You will also need a way to gate part of your instruction register, over to the ALU input (latch or on the bus.) Your addi requires this, to access that field. You may need to sign-extend this (gating multiple lanes to the ALU from a single [sign] lane in your instruction) to get +/- constant support. To do this, it means at least a tri-stating control line and probably also an option that widens the lane, too.

If you haven't gotten the point, yet, it should be slowly dawning on you by now (I hope.) You have provided WAY TOO LITTLE information for ANYONE to tell you how many control lines your execution engine must operate and/or respond to.

Personally? I don't think you've done what you say you've done. If you had, you'd have provided exact details about what you had in place and how it is all controlled so that we could have done less work writing and provided a better answer for you. So I actually don't believe you have done all that you say you have.

It's a good idea to try these things out in Logisim. You'll learn a lot and it's a nifty tool. But it also "cheats" in the sense that you can drop down a subtractor separate from an adder without actually learning how these two functions are really done. (A subtractor is just an adder where one of the inputs comes from the $\overline{Q}$ output of a preceding latch [via another mux, of course] and where the carry-in is changed. You don't use a separate "unit" for that.) It cheats in many other ways which will stunt your growth, as well. (It ignores glitching problems to name just one of many.)

If you are serious about all this, there are some good books I could recommend to help. Have you been able to find a completed CPU in Logisim? You might start with that.

• @Steven If you are interested in details about the control lines (which is mostly what I was talking about here) then take a look at youtu.be/dXdoim96v5A as a first introduction to using control lines within the context of a CPU design. That's probably the best visual I know about right now. (Go all the way through it, too. He has to track down a "bug" in his hardware.) Book recommendations will depend on your background. Can you talk about that a little bit so I can be more selective? – jonk Oct 24 '17 at 0:33
• Thank you for the video recommendation. I have an undergraduate background in electrical engineering which I just entered the second semester of my junior year. I'm interested in computer engineering specifically but my college doesn't have strong representation in that area. I'm trying to self-study the areas they covered haphazardly, control unit design is specifically one I'm having difficulty finding good resources on. Thanks! – Steven Oct 25 '17 at 5:35
• @Steven I think the reason for less focus on the control details for an instruction are because clean, simple logic is applied elsewhere (registers and register files, a bus control unit, and the ALU itself, for example) and the rest is "swept under the rug" of the control details in some mysterious "hand-waving." You know something has to happen and it has to have some order to it. But those issues are left unsaid, far too often. That video I referenced helps you actually "visualize" what needs to happen for an instruction to execute properly. – jonk Oct 25 '17 at 6:21
• @Steven I'm trying to think of a good book on this narrow subject and don't have one to recommend, to be honest. The best way to learn this is by doing it. – jonk Oct 25 '17 at 6:29

The control unit will use the input opcode and control the CPU (write/read from registers, memory or ALU).

As you only use addition and subtraction in your ALU, you can use two bits to control it (Bypass and substract).

Then, for your registers and memory, you have to enable the write to the result register or memory thus, you need two more bits (register write and memory write).

Finally, you need two more bits to select the operands source (from memory, from immediate or from the register read).

Thus I would say, that you need at least 2 + 2 + 2 = 6 signals.

• Thanks. So for controlling register and memory write I will have a single bit output which, if high, will tell the CPU to write to the register, and another output bit which, if high, will tell the CPU to write to memory? Or could I not have a single output bit that when low write to memory and when high write to register? And for your last point with regards to selecting the operand's source, how can I select from 3 sources with 2 output bits? Are the outputs bits independent of each other, or are the combined together (for example 00 = from memory, 01 = from immediate, 10 = from register)? – KOB Nov 16 '16 at 14:48
• For the memory or register select, it's simply the enable bit of the flip flop. If High, the flip-flop takes the value given. For the memory it's the same principle. I would use two independent bits to ensure that you really want to write the memory or register. There are operations where you don't want to. For the operand source, yes those are linked and are used for a 3 input mux for example. – Gp2mv3 Nov 16 '16 at 21:13