Okay. So, we've talked about structural hazard, or we talked about pipe lining basics. And now, we're going to go into the three main types of hazards. Structural hazard, data hazards, and control hazards. Let's start off by talking about structural hazards. Okay. So,, let's we'll review structural hazards here. So, structural hazards, as I said before, occurs when two instructions need to use the same hardware resource at the same time. And there's a couple of approaches on how to resolve this problem. I mean, we can't just throw up our hands and just stop the pipeline, or maybe that is actually kind of one of the solutions. But, you need to somehow think really hard about how to deal with structural hazard. one thing you can do is you can explicitly avoid having different instructions that would be in the pipeline at the same time, use one structure at the same time. And you can do this by the programmer, or maybe the compiler can do this. Next way to go about doing this is you actually have the hardware take care of, basically all of the problems. And, there's some complexities in actually building this. But you want to stall the processor, or stall a portion of the processor, or stall the dependent instructions. or just going to, you, you stall let's say, the earlier one when you go for the contended resource. So a good example of this is if you have one resource two things are trying to use it, you have a priority encoder in there it's, and the priority encoder says, the early instruction gets to use that because if you sort of invert the priority order, you might end up with deadlocks. And another good way to do this is you can actually duplicate the hardware resource or you can add more ports to a memory structure which is sort of equivalent of duplicating the hardware resource. And this is to some extent a solution that is used pretty widely in something like the, the Mips pipeline, the basic five stage Mips pipeline is we actually duplicate certain resources. For instance, there's two memory arrays. There's an instruction memory array and there's a data memory array. And we'll look at an example where those two things are together. But, the simple five stage mips pipeline was really designed not to have any structural hazards. The ISA was basically designed for that to be the case. But more complex instruction sets in pipeline designs, you know, you might have to deal with something like a structural hazard. And even if with the Mips ISA, if you go to deeper pipelines, you might end up with structural hazards and, and, we'll, we're going to talk about that now. Okay. So the first thing we're going to talk about here is structural hazards if we want to unify the memory. So, as I said in the five stage Mips pipeline, you have all the hardware you need for every stage and all the stages are basically independent. But, let's say we were to modify this. And instead have one memory here. And we wire out, and, and, we only have one port into this memory. So, only one thing can access the memory at a time. And we wire the program counter into here to go fetch our instructions. We wire the data out up here into the instruction register. So, it's just wired in the same place as the instruction memory was before. And we take the, where we had the data memory access when we want to do a load restore. And we run those wires down here and we put a multiplexer here to share the address [COUGH] and only one of these resources can use it as time. Hm. Okay, well let's draw the pipeline diagram for what happens with something, something like this when you go to execute a load instruction we'll say, on a unified memory architecture. So, if we take a look at this structural hazard example where we have a unified memory, where we have the one memory here which is replacing both our instruction memory, and our, our data memory. We need to walk through let's use this as an example to walk through the pipeline diagram of how instructions would flow down this, this, this example here. So, let's start off by executing something like a load first. [COUGH] Then, let's say we have an add, followed by an add, followed by an add. Okay. So, this is our first pipeline diagram here. We're going to have the load coming down the pipe. And it's going to execute, or it's going to enter the fetch stage. Then, it's going to go in to the decode stage, then it's going to go in to the execute stage, then it's going to go in to the memory stage and finally write back. The first add comes down here and it's going to go into fetch, so you're going to decode, it's going to go into execute, it's going in the memory stage, follow here write back. The third add is going to come down the pike and then go into fetch stage, decode, execute, memory, write back. So far, it looks like a pretty idealized pipeline. This next add, maybe we should just put an F here. Let's think about this. Is, is this right? Can we have an add fetching from instruction memory at the same time as a load is accessing the memory, this unified memory that we have here? And this is, this is the question. We have this unified memory and we are trying to have two things accessing it at the same time. And this is a structural hazard. We can't, we can't do this. So instead, we're going to put a dash here and we're somehow going to install or bubble or no op this add for a cycle. And then, we're going to use the fetch we are going to use the instruction on memory on the subsequent cycle. And the reason we stall the add and we don't stall the load is because this is a earlier instruction than this. This is a later instruction. We want the earlier instructions to finish first. Otherwise, we might have some deadlock concerns or some deadlock problems. So now, we fetch, we decode, we execute, we use the memory and we write back. And you'll note here this just gets pushed out one cycle because we had to stall here at the beginning, one cycle. [COUGH] And, this memory and this point here is the structural hazard that we saw, that we had to resolve. And in this case, let's say, we stalled one cycle to resolve that hazard. Let's, so now that we've seen how to do a unified memory and what the pipeline should look like for that let's go on to a different example here where we have a two cycle memory. In this two cycle memory, we're going to have stage M0 and M1. We put a pipeline register down the middle of our memory here. But only one thing is able to use that memory at a time. So let's, let's briefly draw the pipeline diagram for something like like this. [SOUND] Okay. So, the second add is going to start flowing down the pipe and it's going to be in the fetch stage, decode, execute, M0, M1, write back. Then, we're going to have the load. So, you're going to go fetch, decode, execute, M0, M1, write back. And now we're going to see a structural hazard. We're going to have this second load here is going to fetch. So, I'm going on to decode. [COUGH] It's then going to go into execute. Now, here's the problem. If we were to put M0 here, what we see is we actually have two different instructions in time wanting to use one resource, the memory. So we need to solve this somehow. Now, how do you go about doing this. Well, there is different approaches and we'll talk about that in a minute. One approach let's say, is you could actually stall the pipline here. So, that was one of our solutions. You stall a pipeline, so we're going to put a dash here to mean we stalled for a cycle. And then, we're going to have M0, m1, and then write back. And you can see that it's basically pushed this instruction back one cycle. But this doesn't happen with other instructions. And the other thing to note is it doesn't happen if you have something like an add after a load here because that's going to go fetch, [SOUND] decode, execute, [SOUND] oh, sorry. It stalls here, too. execute, [SOUND] M0, M1,. And these can be overlapped because we're not, we don't actually have any hazard, in this case. Because there's, there's not a load, loads, or two things are not trying to use this memory at the same time. So, you won't end up with a hazard there.