 Greetings, Risk Five friends. Well, it's time for another video, and you know what that means. I'm building a Risk Five processor, not on an FPGA. So I have a few topics that I want to talk about. It's probably going to be a bit of a short video because there is not really going to be a whole lot of coding, just a bunch of drawing. So the first topic that I want to talk about is the register multiplexer input thing layout. And the last video, I went through it and I was using some 0.1 inch pin headers. And someone rightly pointed out that when you've got a whole bunch of those, the friction is so huge that once you put them together, you're probably not going to be able to get them apart. So somebody else suggested that I look into some of these other sort of high density connectors, and these are 0.4 millimeter pitch connectors, which is pretty small, and I have an image of that here. So this is the printed circuit board layout after I sort of squoze everything down a bit. I was able to compress things, ignore this side part over here. Let's see if I can get it in green, yeah. This side part, I haven't yet figured out what I'm going to do with the control lines, but basically these things down here are the little connectors that I can use. And there are going to be two of them because I've basically split the circuit essentially in half. One for the lower 16 bits and one for the upper 16 bits. It doesn't really matter how separated they are because the data lines just go one half to one side and one half to the other side, and all the control lines are just hooked together. So this is a pretty neat board. The other thing is that this is stackable. On the other side, I have the registers, those are these two things, and I don't have the models for the opposite gender connectors than these, so they're just sort of hanging out here, but you can sort of imagine that the boards can be stacked one on top of the other. So that's kind of neat, and that's probably what I'm going to be going for. The size of this board, I think I got it down to 120 millimeters by 70 millimeters or so, which is pretty small, so I'm pretty happy with that, and I think that's what I'm going to go with. So again, this is not the final circuit, this is just what I've been playing with. Alright, so the next topic, the sequencer logic. Okay, so in the code, basically I had this sequencer card, and it was just this big monolithic piece of code, and what I was able to do was separate out all of the register multiplexer things and all of the non-registered multiplexers, these are the multiplexers that go to the buses, so I separated those out, and then I was left with a few other registers, like one-bit registers for the trap, the ALU, the three ALU condition outputs, and a few other registers here and there. And once I was able to separate that out, I was just left with a bunch of combinatorial logic, and this diagram sort of shows the combinatorial logic. What we've got here, we've got, so just ignore the fact that these are ROMs. There are actually 76 control lines in the entire thing, and there's 20 bits, 32 bits, and something like 35 bits. Some of these are actually duplicates, so it's something more like 31 or 32 bits. So, strictly as a monolithic combinatorial block, that would mean 32 input bits and 76 output bits. Now, forgetting about the output bits, if I were to treat the entire thing as a 32-bit input circuit, that would be essentially one gigaward, where a word is 76 bits. So, you know, if I had a ROM, I would need a ROM that was one gigaward. And, you know, if this were 76 bits, then, you know, figure that's 10 bytes out. So, I would need a 10 gigabyte ROMs, essentially, to do that. And I felt that there was probably a better way to do this, so I looked at it, and I was able to actually separate out that monolithic block into three separate blocks. One block taking only 20 bits input, which is one meg, that's pretty good. Another block, which just handles traps, taking only 12 bits of input. And then another block, which is just handling interrupt requests and loading of the instruction, that can take three inputs and only needed four outputs. So, this is a really simple circuit. The trap ROM is basically the thing that monitors for fatal exceptions and other traps. And what happens is when there is a trap, it basically takes over from the other ROMs, and it injects its own signals. So, that's why there are 76 bits coming out of the sequencer ROM. These 32 bits that come out of the trap ROM get essentially ORD with the other 76 bits. Same thing with the IRQ and load ROM. So, the end result is that I have three sections, and each section has only a very few number of input bits, which is really good. Because I managed to find this flash ROM, and it is a... Well, it says it's 16 megabits, but it's actually one meg by 16 bits out. So, that's kind of convenient. Remember that we have a 76-bit output, so I just need a bunch of these, like five of these. Or, yeah, five of these. And because it's one meg address space, then that's just 20 bits in. So, I just need five of these, and maybe one for the trap, possibly. So, anyway, and these are flash, which means that I can take them out of the board, flash them with an external circuit, and then put them back into the board. Or maybe I can leave it in the board and put in some plugs or something to program them. So, that's pretty nice, because it basically means that if I do make a mistake, for some reason all that formal verification was all bad and wrong, I can just reprogram the thing. So, that's kind of neat. Okay, so, yeah, so that's that. And I guess the final thing is proof mode. So, now that I've kind of gone through everything, and I'm pretty sure that everything's going to work properly, I really need to do an inductive proof on everything. And that is what I'm working on right now. The inductive proof basically means that I'm going to run a simple check, a bounded model check on everything, and then the inductive prover takes over. So, with proof mode, you basically have to write a whole bunch more asserts that you think you don't need, but really what it does is it reduces the state space, because remember that the inductive proof relies on a base case, which is your bounded model checking, and then your inductive case, which is you start during any state and you just go until you hit a bad state. And those bad states can start from anywhere. So, I had to put in a whole bunch of asserts basically saying what were valid states. And again, you know, I went over this before, what you do is you just run your inductive proof and it fails, and then you take a look at the inductive trace, and you see what bad state it started in, and then you eliminate that bad state by putting in some reasonable asserts. So, you know, I did have to put a lot of them in. And here's an example of a fairly reasonable assert, which is when there is a trap and it's a fatal trap, then you're stuck in machine cycle zero. So, in other words, once you've trapped fatally, it just sits there and spins and it doesn't do anything else. Otherwise, the trap actually takes two instruction cycles, and that's why the machine cycle would be zero or one. So, the reason that I had to put this in is that sometimes the inductive prover would say, oh, it's a fatal trap, we'll start from instruction cycle two. And that's wrong, because, you know, that will actually never happen if the machine is behaving itself. It'll never actually get into that state. So, that's why I had to basically say, well, you know, if you're in a fatal trap, then you're going to be in machine cycle zero. There's no way for you to get to machine cycle one. And asserting that that happens helps, because in, first of all, in bounded model checking, you will see that you will never get past cycle zero. And in the inductive proof, that basically says, okay, well, you're never going to end in machine cycle one. So, there you go. So, right now, I'm just working on that. With all these assertions in place, the inductive proof is actually going pretty quickly. In fact, the only inductive proof that is taking a long time is the fatal four section. So, I broke checking fatals into three parts. Fatal one. Let's see. Where do I have that fatal? Fatal, fatal, fatal. Oops, I think I skipped past it. Yeah, here we go. So, here's fatal. For fatal one, I'm just checking loads. For fatal two, I'm just checking the jumps. For fatal three, I'm checking op, op, in and store. So, op and op in because you can have an illegal instruction in there and store because you can also have misaligned instructions. And then fatal four is all the rest. So, it's the all the rest thing that appears to be taking the longest amount of time. So, not really sure why. But anyway, that is really all I wanted to cover. So, things are rapidly progressing. Once I get the inductive proof done, I'm actually going to start building the sequencer because I know what the bus is going to look like. I know what the sequencer needs. I know what all the other cards need. One of the interesting things that I did was I added an exception card. So, here is the exception card which holds some of the CSRs, namely the mCause, MAPC and MTVAL. I also have an IRQ card which holds some other CSRs, the mStatus, MIE and machine interrupt pending registers. So, I had to separate those out because it turns out that sticking them on separate cards actually made things a lot cleaner in terms of the combinatorial stuff. Now, yes, I did have to add some extra control lines onto the bus. And, you know, there's more than a few actually. But it's a cleaner design, I think. And it was also what enabled me to get that big combinatorial block for the ROM down to just 20 bits. So, that's really all I have to say. There's not a whole lot left here. So, as you can see here, we're just waiting for this final thing to happen. I have had several runs before. And again, when they fail, I just look at the trace and then I add some extra asserts. So, this is really the final step. And then once this succeeds, I'm just going to run everything. And then I'll basically call the coding phase done and we'll just start putting some schematics together. So, I guess that's about it. Kind of a short video, kind of a pointless video, but you know, I just wanted to show some progress. So, I guess until next week, see ya!