 This time we're going to be taking the architecture that we've built so far and figuring out how to control it. We want to make it so it runs one specific instruction each cycle and doesn't try to run multiple instructions. We don't want multiple instructions running into each other or causing problems overriding each other's results. Even more so if it's actually trying to do something besides the instructions we've given it. We're going to look at adding control in two different ways. First and perhaps easiest is to simply look for all of those cases where we have sample two wires that are converging. I've got this wire that comes out of the ALU with ALU results as well as this line coming out of the data memory with the load word results. I want to be able to write one of those two back to the registers, but which one I write back to the registers depends on the instruction I've got. So any time where I find two lines that are converging I'm going to want to be able to make a choice there and making a choice means that I'm going to need a multiplexer. So I'll begin by dragging in a multiplexer for the data memory and the ALU results. Then I'll go ahead and move the connectors over so that they point to my new multiplexer. And since I still want the results to be written back to my registers, I'll add a new connector coming out with the multiplexer and going back to the register. This way else I can still get the same results that I had before, but now I can choose whether I take the results of data memory or the ALU and send those back to the register. Looking around another place where I make it such a choice is between the jump instruction and the branch or next instruction. So I'd like to add another multiplexer between this line and this line. So I've moved both of those links over to the new multiplexer and it'll make our connection back to the program counter exactly the way we had it before. Another place where I need to make a choice is between the second source register and the immediate. So there's a multiplexer to choose between second source and our immediate. That turns out to be all the multiplexers that we need because of that issue, but we'll have a couple more that we'll add later. One of the other things that we need to be able to control is some of the hardware blocks themselves. Obviously each of our multiplexers have some form of control, but we also want to be able to control our registers and our data memory. We don't always want to write data back to our registers, so we'd like to be able to control when that happens and when it doesn't happen. Likewise, we don't always want to read or write from data memory, so we'd like to be able to control when that happens as well. For the moment, I'm going to add in a control unit and the job of the control unit is going to be to set all of these signals for us. So there's all of our obvious multiplexers, our registers in our data memory, Another thing is I'd like to also be able to control when I take a branch. I don't just want to take a branch every time the results of my ALU are zero. I'd like to only take them when the results of my ALU are zero and I have a branch instruction. So I can do this by adding an AND gate in here and since I have two conditions that I want to both be true, one of them is that the results of my ALU computation are zero. The other one is that I have a branch instruction that I'd like to run. So because I want two conditions to be true, I can just use an AND gate to make sure that both of them are true if this multiplexer gets turned on. Now, if I have both a branch signal and the results of my ALU computation are zero, then I will take the results of my branch target address calculation. Otherwise, we would just use the address of the next instruction as the results of my branch address calculation. I can also go ahead and add in control line for our ALU. What our control unit here does is entirely going to be determined by which instruction we're running. So its input is always going to come from the instruction. Now we've added all the control that we need to be able to make sure that we only run one instruction at a time. Once we've gone through all the details of what our instructions actually look like in the machine, then we'll still want to come back and add a little bit more detail. We'll find there are still some conflicts and we'll need to address those in terms of what the instructions actually look like and how we make sure that the information they have gets to where we need it to be. And for most of that, we're going to be looking at the area around the instruction memory, especially how it reacts with the registers, the branch target address calculation, as well as the jump address calculation. So pretty much anything that comes out of the instruction memory directly is going to be changed a little bit once we've actually looked at the shape of our instructions, where all their information is, what form it actually takes. And that will allow us to make sure that we actually get useful information to all of our functional units. But for now, our control unit is able to make sure that all of our other elements are doing what they need to be doing. None of them are going to be trying to run some instruction that they shouldn't. They'll only ever run the one instruction that we're interested in right now.