 Well, there's this on. Sound check. Well, there's this on. Sound check. Yay, people can hear me. Yeah, I think I measured it at something like an eight second delay. Ding! Greetings, risk five friends. And welcome to another live stream coffee. So, I just received in the mail some tiny FPGAs. The BX version. And I thought I'd unbox it and see if it actually works online so that if I screw up, everyone can see it. So, let's get started. It's a note. It's completely blank. The FPGA. And a shipping sticker. Don't need that. Okay, yeah. This is what I was hoping to see. A card. And I've got actually five of them. And the reason that I have five of them is because I always need more IOs. So, let's see. Each comes with the tiny FPGA. Testing. Print out. Let's see if we can see that. Nope, it's completely washed out. My camera really sucks. Okay, you can sort of see it. Anyway, it's got a bunch of passes on it, which is, of course, good. Because if they didn't have any passes on it, Luke would not have sent them out. And we have a, yes, tiny FPGA pinout card in the style that everyone knows and loves. And this is the back. Let's take a look at it, actually. 9.9 seconds live latency. That's pretty cool. Okay, wow. That is a tiny FPGA board. That is really small. And there's the back of it. So, that's pretty cool. All right. So, what we've got here, apparently, let me get my tweezers. So, we've got a USB here. And what appears to be a bunch of transistors, I guess, for the USB. This thing in the middle, that's the FPGA. I believe this is the flash where the bootloader resides and also whatever you program for the FPGA. And there's about six megabits of user space in here for you to use as you like. So, this is connected via spy to the FPGA. Initially, when the board is powered up, I guess the FPGA pulls the bootloader over spy from flash which activates the USB thing and we get to do a bootload. Well, why don't we do that then? So, let's pull out the tiny FPGA guide. Let's make this a little bit smaller. I think that's probably good. Okay. So, let's go to the top. Now, I've done this already beforehand because installing software is pretty boring. I'm using Windows 10, so I'm following the Windows thing. There is something for OS 10. And unfortunately, there is nothing for Linux. And that's kind of disconcerting. But anyway, so you install Python 3.6, which I've done. Then you install APIO, which is a tool that makes it very easy to run the open source FPGA tool chain. The open source FPGA tool chain that they're talking about is, well, it's Ice Storm actually, but it's based on EOSIS, which Clifford Wolfe has developed. And basically, this tool chain is able to program any of the Ice 40 chips from, where is it? Ice Storm. Project Ice Storm. Here we go. So, any of the lattice Ice 40s that are listed here. And the one that Luke has put on the board, I believe, is the HX8K, which is the big nice one. We can look at tiny FPGA. And yes, it's the oh, it's the LP8K, which is, let's see, LP1K. Here we go. LP8K, which is a BGA, and it's got 178 IOs, not all of which are brought out, simply because this is a BGA and not a, and it doesn't use like a 10-layer board, so you can't access all of the pins. It's pretty big. It's got 7680 logic cells compared to the previous version, so it's pretty big. It doesn't seem to say that it has distributed RAM, but I think it kind of sort of does. It does have 128k of RAM and 6 megabits of flash. That's on this flash chip right over here. 41 user IO pins are brought out for the low, low price of $38, and they are available now on CrowdSupply. He just released a whole bunch of them on CrowdSupply. So if you go there, there it is, they're in stock. Oh, wait, it says it's sold out. Really? Oh, that was the B2, the BX. The BX is what you want. So yes, you can add them to the cart, so buy them now and make Lucat happy. Yeah, it's so tiny. So very, very tiny. Here is a razor blade in comparison. It's about the size of a razor blade. So, tiny. Can you program it directly with IceProg? Yeah, I don't know. I'm not an expert, so I have absolutely no idea. You can program it with IceStudio. I know that much, because he demonstrated that at Maker Faire. And you can program it using this thing, which makes it easy and accessible, I think, to beginners and FPGAs like me. Okay, so the next thing is to install APIO, which basically goes ahead and installs the IceStorm tools. And you need to install a bunch of, let's see. Okay, so APIO install system, whatever that is, SCONs, whatever that is, IceStorm are the tools, iVerilog, well you need that, because you need to program this thing in Verilog if you're not using IceStudio, which I'm not going to be. And drivers, and presumably the drivers include a serial driver, or a serial USB driver. And it says APIO drivers minus, minus serial enable. So that's fine. So I've done all that. This is the step that I'm up to right now. I've already installed Adam, but I do need to update the boot loader. So why don't we just do that right now. Let's plug it in, and it should, the LED should light and start breathing. Yep, it's breathing. Can you see that? I can't really tell. What a crappy camera. This is a Logitech webcam. It's supposed to be good, but it's not really very good. I need a real webcam. Anyway, I need a real camera. Bring up the command prompt. I would have liked to do this in what resistor, capacitor, burn components value. How to find the value please send me. You are a spammer. I would have liked to do this on WSL, which is the Windows system for Linux, but it's basically Bash. It's Ubuntu on Windows, which is really cool. What are you using this tiny FPGA BX4? That's right. I suppose that I should do that as an introduction. Yeah, that's a very good point. I sort of got ahead of myself. Okay, so there's a whole bunch of IOs here. It says 40 IOs. I'm looking at the card, but the IOs only seem to go up to 31. They start from 1, and they go up to 31. I guess you could use the LED as 1. The clock, I guess, USB if you wanted to. There is some stuff from the flash, but let's just call it 31. Here I have this backplane for the LMR-1 risk-5 processor. It's a discrete processor. It's not on an FPGA, so it's going to be composed of a bunch of cards. Here's an example of a card. This is the ALU card, so it would fit in one of these slots here. Let's see. I've got the register file card right over here, so that would fit in another slot. Basically, I'm going to have a whole bunch of these slots filled up, but I need to test these. I'm not just going to put the whole thing together and assume that it works, because that is just wrong. That doesn't happen. That never happens. I did build this breakout board with two of these PCIe connectors. I could just plug this in and hook up these wires and write a program, but the problem is that first of all, there's lots and lots of IOs. The register file alone has to access all three 32-bit buses. That's already 96 data lines plus the control lines. We're already talking 100 or 120 lines. An Arduino certainly isn't going to cut it, but nevertheless, I'd like to test everything. What I thought is that I would get a whole bunch of these. These are just FPGAs, so we're not dealing with an operating system. We don't have any delays or anything like that. Adam is an amazing editor. It is actually pretty cool. Personally, I use Sublime Text as my main editor, both here and at work. Adam is actually pretty good. It's got plugins. Let's see where it was. I will just go ahead and start a drawing. Let me make this smaller. This window smaller. I'm pretty sure I can. I was kind of doodling before. Here's what I want to do. I have the back plane. I have a card. I have a whole bunch of buses and wires and control lines and stuff. Maybe I should make this just a little bit smaller. Can I do that? Share? Really? I can't exit full screen on this, so I can't see the chat. Maybe I'll move the chat onto another window. I have source one. I have source two, and I have destination. These are the three risk five buses. These are 32 lines wide. I'm doing risk five, the 32 bit version. Already, that's 96. Let's see. Destination, you have a right line. For source, you have a read line. I also put some extra control lines in here. I put four control lines on each of these to control which byte out of the 32 bits is being accessed. We have the lower lower byte, the lower upper byte, the upper lower byte, and the upper upper byte. That's already five additional control lines. We already have 96 plus 15. The ALU has an ALU output enable. The shifter has a shifter output enable, so that when I need to access the ALU, it does something. The ALU in addition has some boot lines, and I think there are four of them that initializes the RAMs that are used in the ALU. There is also a function, and I think I also have four lines for that. This is on the order of ten lines right there. That's all that I've built. I haven't built the instruction decoder, or the memory controller, or anything like that. Already, we're up to 32 times 3 to 25. Let's just round it up and just call it 32 times 4. That's 128 lines. What I want to be able to do is control at least some of the 128 lines and then read some of the other 128 lines and basically send test patterns and make sure that I get the response that I'm expecting. That way I can test each of these cards individually. The idea is that I want to make another card. That's the test card, which has the tiny FPGAs on them. Tiny FPGA BX. Now, each tiny FPGA BX has 31 lines. Well, then I need five of them, and I have five of them. That's basically my plan. The idea is that I have five of these mounted on this card. These are BXs. One of them is the master, and has the USB master. This is USB. That would go to the computer. The master would basically send out a sort of a clock signal that goes to all the other FPGAs and also itself so that we can deal with the delay on this wire instead of the master thinking that the clock that it sends out is the clock that it should use. What that does is it sort of synchronizes all of these FPGAs so that they can all send their signals out at approximately the same time. It won't be exactly the same time, but I don't care plus or minus one nanosecond or even maybe plus or minus 100 nanoseconds. I don't really care because my processor probably can't go faster than 10 megahertz anyway. I can assign each of these lines. If I have 31 times 5, so I have 155 lines, that's 128. That's something like 27 lines available for whatever I want. It would be nice to maybe hook a display up to here using some of the lines. Maybe hook some buttons up. That's my drawing of a button matrix. Here's a little, maybe it's a screen, maybe it's an LCD screen, or maybe it's just a bunch of LEDs or something. But anyway, that's the idea. I basically push a button. The FPGAs go ahead and output a pre-programmed pattern. They wait for a fixed amount of time and then they read back the control lines and then they compare it to what they're supposed to get. If the compare fails, well, it stops and maybe displays something on the display. Otherwise it just continues. The patterns will have to get loaded from something. I'm not sure what. I'm thinking that maybe there's a separate flash over here that I can program with the patterns that I'm expecting. Then when this system boots up the master reads the flash, sends the expected patterns over to the other FPGAs and of course itself and then begins the whole process. That's my idea. That's my plan. I hope that makes sense. Both to you and also to reality because if it doesn't I will be very disappointed. Let's take a look at the chat to see if there's any of your LMR display so far. Thank you. I appreciate it. Can you sing it live for them? I'm building a risk-ride processor not on an FPGA but I'm using an FPGA so I'm allowed. Let's go ahead and what were we doing? Updating the bootloader? This thing? Tiny Prog? Let me go ahead and maybe make this a little bit bigger. A little bit bigger. How about that? I've got it hooked up. Let's do tiny. Can I make this bigger? This is kind of small. Properties. Fonts. Bigger fonts. That's better. Tiny Prog minus minus update bootloader. There's an update available. Yes, fetching stage one. Wow. It actually works. Now it's waiting for it to reconnect. Except why waiting for stage one to reconnect? Oh boy. Let's run the updater again and hopefully it's been programmed. Am I using an MX brown keyboard? I forget what color keys these are but they're the semi-clicky keys. They are MX keys but these are just the keys on my laptop. I specifically chose the somewhat clicky keys because I like those. I highly recommend a keyboard called DOS keyboard, D-A-S keyboard. They make the best keyboards with whatever keys you like and I love them. Anyway, only one board, all connected and active boards are up to date. Excellent. So it actually did write the bootloader. It updated it and I guess just the Tiny Prog updater has a bug in it where I guess it doesn't exactly reconnect but it's all good. It's all good. The next step is to install Adam which I've already done and I've installed all the plugins. So let's just go on to the first project tutorial. Connect the USB cable. I've already done that. Copy the template project which I think I've already done. Anyway, let's start up Adam. Let's make it... I'm going to be working with Adam mainly now but I also need... Open up Adam from File. Do you ever use Linux instead of Windows? I do at work. We exclusively use Linux but not at home. I sort of got out of the habit. I used to use OS X and I just got tired of not having all the Windows programs that I use. I also use the Windows Linux subsystem which is this. This is a full-blown Ubuntu distribution. I could even do your name minus A and it shows... What does it show? Well, it says it's a Microsoft Linux system. Anyway, I used that on occasion. Copy the template project from the tiny FPGA BX repository. I did and I don't remember where I put it so I guess I'm going to have to download it again and put it somewhere. Let's go to the tiny FPGA... Oh, it downloaded something. Let's open it up. What do I get? I get 7 zip opening up on another screen. Tiny FPGA BX master. This is the thing. I'm going to go up and extract this to my main user directory. I guess I'll extract it to my main user directory. Done. Back to the guide. I've downloaded the repository and it says open up atom, file, open folder and go ahead and do the thing. Open the folder, go to me, users. It was called tiny and I have to open up APIO template. Required APIO version greater than .30. Did I screw something up? I'm pretty sure I did this. Well, let's continue and hope things work. Oh, and rename it BlinkProject. Let's go ahead and rename it BlinkProject then. Go ahead and call it PGA BX master. It's no longer the master really. And call it BlinkProject. File, open folder, BlinkProject. Huh. It says that the required APIO version has to be less than .4. I'm not sure if I believe it, but anyway. And it did have me installing .4.0. So, okay. Navigate to the BlinkProject, select folder, which I did. From the APIO menu, select upload. The project will automatically be built and uploaded. Okay, APIO. Was it build or upload? Upload. I think something's happening. It's running things. It's erasing. It's writing. It's reading. And well, boom, look at that. It's blinking. Fantastic. I don't know if you can see that. Because I've got a really shitty camera, but yeah, it's blinking. It's blinking in the SOS pattern, which is a pattern that I would not have chosen. Let's take a look at the dialogue. Let's open this. Let's close the welcome mat. Can I make this bigger? I'm sure I can. Probably in pref settings. Settings. Font size. How about 18? Control and scroll. Yeah. I'm kind of reluctant to use control and scroll because I think if you do that in Chrome, it actually zooms. Very nice. Very cool. Okay. Here it is. This is the Veralog. Let's see. We start with a module called top. These are the quote arguments. I'm not by any means good at Veralog. If I do something in Veralog, I learn just enough to do it, and then I do it, and then I promptly forget everything that I've learned. I even wrote notes on what are the basic Veralog things. I know that there are things called modules and registers and wires and stuff. I don't know how familiar you are with Veralog, but I'll just sort of step through this and maybe explain it to you like your five. We start with a module, which is basically kind of like in programming it's a class where it contains both variables and behavior, and you can instantiate it and create as many copies as you like. These are the equivalent of, well, I guess if it were a class it would be constructor arguments maybe. How much was the board? $38. Oh, Adam is running inside Chrome. Huh. Interesting. Oh, yeah, VHDL. Don't talk to me about VHDL. It's just because I don't like ADA. VHDL is sort of more ADA-like, and Veralog is more C-like, and I just like C. Unsubbing. What? I'm sorry, I'm going to have to unsubscribe. Okay, that's okay. I mean, you know, my position on profanity is, there's such a thing as casual profanity, and I think it's accepted, but I realize that, you know, on the bell curve, there are just going to be some people who don't accept it. So that's okay. I don't blame you. Anyway, let's see. Okay, so these are sort of like the arguments to a function, right? So you've got an input wire called clock, and you've got two outputs called LED and a USB pull-up resistor. I wonder why. Okay, well, it explains why. Thank you for comments. So, assign USB pull-up equals zero. So, let's see, drive USB pull-up resistor to zero to disable USB. Okay, I'm not sure why you would need to do that, but okay, I guess that's something I will have to remember. Make a simple blink circuit. Okay, so first we have, so first we define a 26-bit register called blink counter, and we define 32 signals, these are wires that don't store state because they're not registers, called blink pattern, and this is just the blink pattern, 1-0-1-0-1, blah, blah, blah, blah. So that's the SOS pattern. Okay, and then we have an always block, and I forget what these blocks are called. There's continuous assignments and procedural assignments. Well, anyway, what this block does is it looks at its sensitivity list, that's what the at is, and anytime something changes on the sensitivity list, this block runs effectively. All the blocks run in parallel, right, because these are translated directly into hardware, and all the hardware is in parallel. So, you know, you just sort of have to put yourself in the mindset that all of these things happen in parallel. This particular block happens when the clock has a positive edge on it, and what we do is we take whatever is in the blink counter register, we add one to it and assign that to the blink counter. So on the positive edge, we're just going to increment the blink counter, and that's it, that's all this block does. While it's doing that, we also have this continuous assignment statement. Basically what that does is it takes whatever is in the blink counter register bits 25 through 21, and accesses the blink pattern signal, which remember is a 32-bit it's just a 32-bit signal, and we're taking the upper 5 bits of the blink counter, so that's of course 32, and we're assigning that to the LED signal, which remember is an output. So basically there is a 16 MHz clock on board, this thing, which is connected to the clock pin, and I'll get into the pins in a moment. So basically we're running this counter at 16 MHz, and every time the blink counter's upper 5 bits change, we read in the blink pattern and assign it to the LED. And you can tell that I'm a procedural programmer, right? I'm obviously no FPGA expert, because if I were, I would have never described it like that. Really what's happening is you have to think of this register here, and you have to think of wires going to some circuit that is accessing these 32 bits, and is always outputting to LED, to the LED signal. So it's kind of this funky mindset that you have to get into. Alright, there's also this pins.pin configuration, and there's a lot of elements in here, and a lot of set IOs. So I'm not really familiar with this, but I guess there are these pins, and these look like BGA coordinates. So, okay. Yeah, so this is it. Okay, so on the BGA there's pin B3. That gets connected to a signal word that we can refer to in our modules as LED. Same thing with USB positive data, USB negative data, and USB pull up, and clock. And that is the thing about the 16 megahertz clock. There is a 16 megahertz oscillator somewhere on this board, I guess. And it's connected to pin B2 on the FPGA, and we can refer to that as a clock input. So that's this. So what we're really doing is we're connecting this module directly to the pins that we call clock, and LED, and USB pull up. And apparently that is all you need. So the thing about Veralog is that you have to have a top module. I don't know if it needs to be called top. I don't think it does. I think you specify the name of the module that you want to be the top module. But then you can think of that module as instantiating other modules, which may instantiate other modules. So it's basically this tree of instantiations of other modules. So that's why this is called top, really. And you can see that it's not instantiating any other modules, which of course would be nice for a larger design. So let's take a look at some of these other things. It doesn't have to be top and quarter. I don't think it needs to be called top. I suspect that the shell script says what it is. Oh, there's install. That's the initialize. There's hardware. ASC, bin, and blif, which are generated. But yeah, I don't actually see anything that tells you that the top module is called top. So I'm just going to assume for now that the top module has to be called top. I need the welcome guide. Or maybe the project looks at the verilog files and if there's only one, it uses that as the top? I don't know. So that's actually working, which is nice. So what I thought I would do and I'm probably not going to succeed, but here, let me... It's nice that this just worked right out of the box. That's kind of unusual for open source projects. Yes, by the way, everything that they use is open source. The synthesizer is open source. The place and route algorithm is open source. The boot loader for this is open source and this is all open hardware, which means that you could actually build your own, which I definitely don't suggest considering that it's got a BGA on it. Absolutely exactly. Yeah, I basically came from C in Java and verilog makes sense to me and VHDL does not. Well, it's a good thing that there are two things to choose from. Interestingly, the open source, the ice storm tool chain, natively uses verilog. If you use VHDL, I think it tries to translate it to verilog first and of course, sometimes it doesn't do a very good job. I guess it's a verilog first world. Let me make the video a little bigger. There's a story behind this thing. This is a display that I'm going to be using and I built this myself. I designed it. It uses a Haltech chip This is this HT1632 LED driver. It's convenient because it's 32 by 8. These modules here are 8 by 8 modules. Let's see. Do I have a bunch of these modules? Modules I'm going to need a bunch of these because one of the cards in my backplane is going to be a display driver so that I can display all of the register contents. There are 32 registers and each register is 32 bits. I'm basically going to need 4 of these side by side or actually 16 of these arranged in an appropriate matrix. I bought online this kit that purports to be a 16 by 32 matrix of LEDs that you can program using these pins over here. I built it and it didn't actually work. It lit up but the LEDs actually just blinked. Some of them were on. Some of them were off. Some of them were sort of on and sort of off and they were sort of blinking in this irregular pattern. I looked at the circuit board and I noticed that there weren't any current limiting resistors on this. Usually with an LED unless you have a specialized chip that can drive LEDs you need a resistor. I was like what the heck is going on? I looked at this and we've got each matrix has a 74,595 on it and that's I think it's just an 8-bit register. There's also 74,138 and a 138 is a 3-8 decoder. Two of them together makes a 4-16 decoder. So let's see. Each of these sections is 8 by 16. There's some way where that's the individual LEDs by manipulating these things but the important thing is that from the 595 there's just a straight wire to the LEDs with no resistor in them. There is a transistor in there. The transistor is connected to commons so basically you have to scan the LEDs and that turns on each section of LEDs voluntarily. But again, no current limiting resistors, no nothing. So I looked at the specs of the 595 and it says in its absolute maximum that the output is limited to something like 50 mA or 20 mA or something like that. So I think the designer of this board, which this came from China, from somewhere in Shenzhen I think the designer of the board felt that that meant that the chip could only output 20 mA and that if you tried to draw anymore it would actually just clip at 20 mA. Well as far as I know that's not how chips work. If you exceed the output specification of a chip you basically drag the chip down and possibly damage it. In this case apparently the current was pulled from the chip, the chip started to malfunction and it actually turned itself off and then it turned itself on again. And of course it would do that irregularly. So that's my story about buying these stupid kits. These were 10 bucks each and I thought well that's kind of a steal if it really is this huge, what is this, 16 by 32 matrix because then all I need to do is put two of them together and I've got my register display. Well that was a fail. These boards actually don't work. Nevertheless I got a whole bunch of these and I know how those work. So I decided to design my own board based on this Hulltech chip. And the Hulltech is an LED driver but you do need to put external resistors on it. It's not one of those special LED driver chips that have an integrated resistor. And why would you? Because of course LEDs come in all shapes and sizes and things. So you would need to specify the resistor yourself. So that's what I did. I basically built this and I connected it to the chip and I made a few mistakes along the way. I had to re-spin the board but it does actually work. And I have an Arduino program that actually does work. One of the weird things that I found about this Hulltech chip is that if you look at the block diagram you can see that there's up here VDD and VSS. That's the logic power supply. And over here on the LED driver there's LED VDD and LED VSS. These are described as the power supply for the LED driver. So I thought okay well what they're doing is they're driving some MOSFETs in the LED driver and the MOSFETs are connected to a separate power supply. So I said well that's great because I do want to feed the LEDs with maybe 5 volts and the rest of my system is a 3.3 volt logic system. Voltage agnostic current limiting. Oh yeah. That would make sense. But again you have to be able to adjust the current somehow and I guess you can do that in these special chips. But anyway this just connects common and the other signals to one of these power supplies. The neat thing about the Hulltech chip is that if you have anode common or cathode or if you have common anode or common cathode this will work because there's a register that you can set which flips the polarity of the signals which is really cool. This is a very versatile chip I really like it and it's fairly cheap if you can find it. And I could only find it from place in China and I'm like great. Sourcing more things from China. And the last time I tried to source a chip that I couldn't find from China I got a fake one. Well anyway I got these and they sure look legit. They seem to work. So the thing that I was talking about about the separate power supplies is that they don't actually seem to be separate. First of all of course you would want to connect the VSS together. That wouldn't affect anything. But I thought okay I'll use 3.3 volts on VDD and I'll use 5 volts on the LEDs power supply and everything will work out fine. Well it didn't because I hooked up VDD to the 3.3 volt output of the Arduino. So the Arduino board that I'm using is this Team C 3.6. Clearly not as Team C as tiny so apparently Team C is bigger than tiny. And so you basically feed this with a voltage between I think it's like 3.6 volts and 6 volts. And it's got a regulator on it that regulates it down to 3.3 volts. So I thought okay well I'll use that to power the logic part of the Haltech chip. And then I'll have a separate 5 volt power supply which I'm using to power the regulator. And I'll just hook that up to the LED side of this. And well I measured the voltages and apparently the output of this regulator went from 3.3 volts to 5 volts. And I'm like why? Well it turns out for whatever reason that I guess when you run two separate voltages on here both pins take the higher of the two voltages. So basically what I was doing was I was feeding the output of the Arduino's regulator with 5 volts which of course it survived. The board is fine with that but it just means that I don't think I can actually run the LED side at 5 volts. Which is okay. I can run it at 3.3 volts and just adjust the resistors. So anyway, that's my story. And I purposely designed this board. I purposely designed this board to be slightly smaller than the size of this so that I could just put multiples of these boards together and hopefully it would look a little bit seamless. The other feature of this board that I built is that there are these screw holes here. And if you just put the board together, well the screw holes do nothing. There's no point in them because now you can't get at the other side. I figured out from other kits that are sold that what you do is you put screws into the screw holes first then you solder the matrices and then basically what you've got is a threaded rod that comes out. And then you can just put this down onto something and then tighten it up with a nut or something. So the idea is that you would build a whole bunch of these with screws in it and then you just sort of put it into your main container thing and just tighten up the nuts and you should have a nice display. So that's the idea. I would have a back plane, I would have a card, and I would have a bunch of wires that go to this display which sits on the front of the machine and then you can see the contents of the registers. This would also be used for a debug card where you could see the contents of the buses and maybe some of the control lines. So that was my idea. So I have an Arduino program. So let's make this video a little smaller. Maybe put it over here. So I have this Arduino program over here and basically all it does is it turns on a few of the LEDs. And I thought that it would be nice to write an analog module that does exactly the same thing as this. And that way I could hook this board up directly to the outputs of the FPGA. And that would serve as the output of my tester. So maybe I could have LEDs marching across the screen as it does each test. And then maybe it could blink if something went wrong. These are actually red and green LED matrices. I've only connected to the red matrix to the red LEDs. So it would be kind of it would have been nice if I could do both red and green, but I figured just one chip to drive the red sections is good enough. Besides red, all red LEDs is very retro. And I like that. So if I had both colors I could do green for tests that pass and maybe red for tests that don't. But anyway, so the idea is that maybe what I could do is I could have in the FPGA a register for each one of these LEDs. And then I would have a module which is connected to those registers and reads the registers constantly and sends out the control signals required to display those registers as dots on the matrix. And that's about as far as I got in terms of planning. So everything from here on is just complete fumbling. And I'm not sure that you would be interested in seeing that, but let's see how far we get. So what I'm going to do is can I create a new file here? I'll just call it for now, just matrix dot v. So let's comment this down. Driver for a 32 by 8 matrix of red LEDs module. I'll call it matrix 32 by 8. So what do we need to do? We need to define the inputs and there's a semi-column that goes on the end. So what are the inputs? Well maybe I should begin by describing the signals. So let's go to the sketch pad and talk about the way the signals are supposed to work. Where's my drawing glove? I lost it. Okay, anyway. Okay, so there are pins. There's cs, there's wr and there's data. And I think those are the only important signals for the whole texture. So the idea is that you drop cs and for each bit of data so right would be like this. And then you do this. On a positive edge, the Haltech chip registers whatever your data is. So I'm just going to draw that like this. So the data is whatever it is and then it's whatever it is next. So here's another bit. And that's basically how you clock data into the thing. Now the Haltech chip uses commands. Let's see. So one of the commands that I send is, let's see it's in the back somewhere. Yeah. Okay, so one of the commands, it starts with 1 0 0 1 0 0. And then you do a system disable which is 0 0 0 0 0 0 and then a bit which doesn't matter. So they call this the command ID. This is the command and this is an I don't know. I guess they treat it as part of the command, but every command seems to end in a don't care bit. I suspect that that's because the internal circuitry actually reads 8 bits but requires an extra right clock to sort of register the actual command and then it doesn't actually pay attention to whatever bit that is. So we need to output 3 bits and then 8 bits of command and then 1 bit of this. Now when you're writing multiple commands you don't have to send command ID again. You just leave chip select low and you can clock something else in. So first of all let me call this system disable. That basically turns it off. The next thing that you can do is set the common option and this is where you specify whether the commons are common anode or common cathode and there are actually 2 configurations where you can have 8 commons or you can have 16 commons. Now in my case I have 8 commons. So the command for this is 0010 and 00xx followed by that extra bit. The 00 here specifies what is the commoning option and there are 4 possibilities. 2, 1 bit controls whether you have 8 commons or 16 commons and that determines how the outputs are divided. And the other output specifies whether it's common anode or common cathode. So in any case this is common cathode and 8 commons so I need to send this. There's a PWM duty cycle so you can actually specify how dim the LEDs are in any one of 16 values. So the command here is 101 don't care and then for fully on which is what I want is 1111x so there's that. Then you can turn on the LED duty cycle generator. And what that is is it basically turns on the internal oscillator and starts its scanning routine. So we need to send that command. So that's 0000 0011x this is LEDs on that point you can issue the final command which is to enable the system again. So that's 0000 00001x so that's system enable and then you can disable the chip select. So that's basically what we need. So we need something that can clock out a bunch of bits. So how many bits how many commands? 1, 2, 3, 4, 5 commands 9 bits per command plus 3 bits for the command ID. So that's 48 bits. And this is going to be a fixed pattern so the first thing that my module needs to do on reset is output these 48 bits in this scheme. So let me go ahead and what do I do now? Do I do this? Oh, yeah, okay. That's cool. So the first thing that you always want is a clock. So we need an input clock. The next thing that you typically always do is you include a reset and for some reason traditionally this is a negative reset so I'm just going to do that. And for now I'll just leave that like that and we're done. Do I need a trailing column? No. So this is the input clock active low reset. Okay. So what's next? Let's close it with an end module. So now remember that I had something equivalent to this pattern, right? And it was 48 bits. So what I'll do for now, I guess I put a tab in here wire and it's a 47 down to 0 and I put in the name. So this is the init pattern equals 48 tick binary that's the way you specify a binary literal, you know, and then stuff and it starts off with 100 and you know we continue. So I'll just fill this with zeros and fill it in later. Okay, so that's our init pattern. Okay. So let's see. Always at positive edge of clock, I want to do something. So I always want to do something on the positive edge of the clock. So if the negative reset is low, then I need to put it in I guess initialization mode. So I will need I guess a register called init mode. Respect the use of caps for port names. Well yeah, I think I'm only making this capital because these were capitals over here and I just wanted to make them capital because they're actually output or input pins. This strictly speaking cannot be an input pin. It could just reset the matrix itself. So that's why I'm making it lower case. I don't know if there's like some accepted convention, but anyway Okay. So now what I need to do is if I guess it's bang is that the syntax? If not reset, then begin. And what I want is to set init mode to so there's this thing where we should use a two flip flop synchronizer on the end reset to prevent metastability issues. Okay. Okay. So I kind of sort of get what you're saying but I'm not familiar enough with the pattern to just be able to rattle it off. So what I'll do is I'll put it to do in here. How come synchronous reset versus asynchronous? Yeah, I really don't know this is just what I chose because it's easier I guess. So I'm going to put it to do here maybe two stage. So init mode gets one bit binary one. Okay. So what that will do is it will start off so now it's a reset signal not a clock. It's not clocked but I don't know. Again, I'm no expert. I'll just make it so that it works and then maybe later on what I'll do is I'll go back over it and try to stick with conventions especially style guides that sort of thing. Okay. So the next thing is that do I do this always at big edge pause edge init mode? I don't know if that's the right thing to do. So this is a block that's running in parallel. So the moment it detects that init mode went high. This is probably going to be a bad idea. I really need, I guess I need a counter don't I? So let's make a counter. It needs to have at least a count of 48. So let's make it count up to 64 which means that I need six bits. So five down to zero counter. Let's call it the init counter. And then of course I want to initialize that counter. It gets six bits. So now I have a counter. Put it else in the clocking block and then check for init mode. Okay. So like this. End else begin? No. So when not in reset it checks for init mode. End else if so like this. Oops. Uh oh. I hit a key. Okay. So presumably what's going to happen is on one clock it's going to detect that reset went low and it's going to do this stuff. And then that's it. And then on the next clock it'll check init mode. Okay. Right. So if we're in init mode then what we want to do is output a bit from the init pattern. Let's see. How do they do it here? Well first of all we need something that increments the counter. I'm not sure when we're supposed to initialize the counter. How we output. First of all I do need some output signals don't I? So let's make an output signal output and I'll just call it negative cs. Click select to matrix. We need an output nwr active low right clock to matrix and we need an output data which is the data output to your matrix. Okay. So let's see. I guess when we go into init mode okay I think. Okay so I'm not sure how this is supposed to work but init counter equals 6. Is that how you do equals? Yes. 6 bits 0 begin. I do want negative cs to get 0. I also want negative right. Actually here what I want is negative right to be initialized at 1. I want negative cs to be initialized at 1. Okay so here we drop cs and then I actually want to wait one clock maybe I really need a state machine here but I'll just do this stupid naive way. Let's see. So first of all it's 118. I've been at this for about 80 minutes. I think I'll probably go maybe until 130 because honestly looking at me fumbling around coding verilog that I'm not familiar with is probably very boring and I'd rather just sort of like present the finished product and just go through it line by line explaining what each line does and why. This isn't very interesting so I think I'll probably just stop the stream right here because honestly there's a lot of research that I need to do. So anyway yeah that's pretty much it so hopefully next time I can actually show a video of the tiny FPGA driving this matrix and doing something. So that would be kind of cool. I guess that's about it I suppose. I'm sorry that there really wasn't very much more exciting happening but hey tiny FPGAs going by some because they're useful to have around the house I guess. Alright well take care. I'll see you and have a great day.