 OK, so I wanted to talk about the I4TFPGA, because I've been working with them quite a bit lately. And I thought it'd be a nice introduction. So it's going to be very quick, just showing off some of the things I've worked on without too many details, I mean, depending on which thing. Hopefully to give you the taste to actually try and work with them, or if you have any question on any specific project that I will present, just ask. And I'll try to answer them. This is mostly basically a series of pictures, so I'm going to be just commenting on them. So first, a quick introduction to the I4TF family. I like them because they're really small. This is the UP5K, or the I4TFUltraplus 5000, which is one of the largest one. By ultraplus, they mean ultra low power, which mean it's slow. That's a translation. So don't expect, you know, artics or exciting levels of performance, stuff like that. The frequency we're talking about here is 50 to 100 MHz, or stuff like that. Getting your logic to be clocked at several 100 MHz is not something you're going to achieve there, not without a lot of care at least. Another reason I like them is they're fairly easy to use. Like, you don't need 10-voltage rails. You just need the IO voltage that you use, 3.3 volts, then the V-core, which is 1.2 volts. And it's being low power. You can actually just use a linear regulator, and that works just fine. The first board I designed for the I4TFUltraplus, I didn't know what kind of power consumption it's going to have, so I put a switching mode power supply capable of providing one amps. And I did a test design basically toggling every flip-flop in the FPGA at 100 MHz while overvolting it. And it was consuming like 40 milliamps or something. So there was quite a bit of margin there. I would say, if you know what I mean. Actually, the switching converter has a special low power mode, and it never leaves the low power mode, like the discontinuous conduction. Yeah, it's a TI switch. And this one is particularly available in the QFN48 package, which means it's fairly easy to solder at home without big equipment. Even just a soldering iron is enough to solder it. That's the general structure of the UP5K. It has a bunch of hardware IP. So it has two SPI cores and two I2C cores, which you can use. They're really meant to be used from a soft-core CPU inside it because they have a bus interface with some registers and stuff like that, like you'd find in a normal microcontroller basically. Something else interesting it has are those SPRAM blocks. So it has one megabits of SPRAM stands for single port RAM, which is fairly unusual in smaller FPGA to have that much SRAM present on them. It's really useful to have it on board basically because being in QFN48, you don't have that many I2C. It has DSP blocks, eight of them. So they are 16 by 16, and so you can do multiplication. So if you want to accelerate some function. And it has these are much smaller block RAMs, but they're much more granular. They're only four kilobits, but they're dual ports. So you have one read port and one write port. You don't have like dual read, dual write. There's like 30 of them for small 5.0s and stuff like that. And then you have the actual logic slice, which is a forward-based architecture. They're grouped by eight. You can use or not the flip flops. And so you have classic lutes and a flip flop. And we'll see more details later. Some other interesting features is the NVCM, which is a non-volatile configuration memory. So it can store its own bit stream internally. Does this one time programmable? So yeah. Apparently, some people tested it's more like three, four times programmable. So you can actually overwrite it a few times. But it's really not guaranteed at all. Otherwise, it can just fetch its configuration from a normal SPI flash. And most of the pins that are used for configuration can be reused for user IO after, which mean that you can have the bit stream for your configuration. And then some user data stored in the same flash and access it from user. Basically. That's the detail on the PLB structure. So you have some dedicated carry logic, which is really inflexible in the sense that if you're familiar with Xilinx, FPG, and stuff like that, the carry logic is a bit more flexible. And you can actually abuse it to implement something else than an actual carry logic for an adder. In case you're not familiar with that. Here, really, you can implement an adder with it. And that's pretty much it. Then you have a fourlets, which is a lookup table. So it provides any function, depending on the four of the inputs, optional registers. And what's important to note is that the group by eight and the clock enable and set reset lines are actually shared by those eight, which means that if you have a flip flop that use an enable, and that's the only flip flop that use that particular enable signal, you just will sacrifice basically seven other flip flops for nothing. Because you can't use them. Something that I found really strange in that FPGA contrary to Xilinx is that the set reset here, when it's configured in synchronous mode, is actually gated by the clock enable. So if clock enable is at zero and you send a reset, the flip flop won't actually reset. That's rather strange. That means that when you code your logic, you have all the advantages. You should basically use asynchronous resets. As the synthesis tool will have no choice, but to basically do a logic or between the resets and the clock enable signal to generate the actual clock enable signal. Just a little detail, but if you have a lot of flip flops that have resets with clock enables, it can drastically reduce your logic use and improve your timing. That's the board I've been working with mainly. I started with a board from Lattice, but they're rather limited. And this is a board that's becoming available, which is really nice. Because when you have the UP5K itself, it has two P-mods, three P-mods, sorry, connector. So if you're not familiar, they kind of are standard for extension. It's basically 8IO and power here, here, and here. And the FTDI is used for programming the flash. And once the programming is done, you can actually use it to communicate with the host to send, receive data. You can either use SPI or UART to talk to the host, or both at once. Actually, they use different pins. You have a very large flash, which is like 64 megabits, I think. And the bit stream uses only one megabits. So if you want to put user data in there, that's very doable. So something else about that FPGA is that it's supported by an open source tool chain. So you don't actually have to use any of the latest tools if you don't want to. You have uses, which does the synthesis part. So for those, maybe I should have asked, who doesn't know what an FPGA has? OK, good, because I didn't explain, but yeah, whatever. So the flow in an FPGA is often split into two tasks. The first one is called synthesis, which basically takes your very low code, whatever, your HDL, and converts it into logic elements that correspond to your FPGA family. And that's what we use this does. And it will generate a net list, which series of LUTs and registers and stuff like that. And then the next step is done by next PNR. And that's place and route, which is basically take those logic elements and actually decide where on the FPGA to place them and how to connect them using the available cells that are there and the available routing that are there. And that's done by next PNR. Now, those tools are constantly improving. But if you're looking for the most extreme timings or stuff like that, the vendors tools still provide, like an advantage, they're still better. Although the gap is closing rather fast with new algorithms and stuff like that, but yeah. So one nice thing about those FPGAs, you can overclock them, of course. So I noticed in the vendor tools that when you simulate the timings to know what frequency will your FPGA reach, your design, what frequency can you run it at. And you have to input what's your tolerance on the temperature. Do you want it to work from minus 20 to 85? Or are you going to be at the constant 25C? Or stable is your power rails? Like can it dip to one volt? Or is it going to be a consistent 1.2 volt? That kind of stuff. That has huge influence on to the results of the timing. And so I was wondering, OK, well, what's the actual speed like instead of what's predicted? And so I did two tests. The first thing is to take the timing model that we use in the open source tools and predict frequency and then measure it. And so I did that with a ring oscillator. So you're basically in the FPGA, you ask him to do a chain of inverters. And if you use an odd number of inverters, well, it will oscillate because it constantly switch. And so using the timing model that you have, you predict how fast it's going to oscillate. And then you compare that with the frequency that you actually get. And that's this result. Like the timing model we have for the routing logic and the logic element and the routing predicted that it should oscillate at 11.1 megahertz. When you actually measure it, it's 17.44. So there is definitely some margin there. And the other thing is the dependency on the v-core and temperature. I didn't actually test temperature yet, although I didn't see a lot of variation there. But I mostly tested the OK, it's nominal 1.2 volt. But what happens if I provide it with 1.1 and 1.3 kind of stuff? And so I used those two test boards. They're basically other boards that are meant for something else where I just populated the FPGA and didn't populate the v-core regulator. And I just feed in a voltage from an external power supply, basically. That's for the LP384. That's the smallest FPGA in that family. It comes in QFN32. It only has 384 logic elements, which is really small. But it can still do very useful things with it. And that's for the UltraPlus 5K. Again, just the FPGA, basically. What's necessary to load a bit stream in it and manually feed the voltage. And that's the result I got. So basically, I normalized the output frequency, which means at the nominal 1.2 volt v-core, you get one normalized frequency. But you can see that if you push it to 1.4 volts, you almost get 50% faster frequency. I also measured the power consumption. It's not graphed, but it's not significantly higher. The heat is also not, I mean, I can't. It doesn't show up at all in the thermal camera. Like I couldn't see any difference between the board and the jib itself. So it's so low power that the heat doesn't matter, which means if you want to push your design a little bit, well, instead of putting a 1.2 volt v-core regulator, you can put a 1.31. And it's just going to go faster. But on the other hand, you also have to be careful that if you voltage somehow dips, yeah, it's going to fall pretty hard. The current timing models pretty much are there. So that's basically, we simulated the worst case, basically, it's around here. So some fun applications to do with those. The first one is digital to analog converter using PDM, also known as delta sigma. And this might look more complicated than the standard delta sigma. But if you just go with the basics, just take this pin. You just go through a resistor, well, two in series. That's just one. And then capacitor, that's basically a low pass filter. And so you just output a density of purses, and you average them. That gives you an analog voltage. Then you can add the second resistor here, which, if you follow this relation, kind of gives you more resolution bits. The general idea is that those two resistors, they form a resistive adder. And so you can have the first MSB, basically, which fix globally where you are on the voltage range and then use the LSB with a much higher resistance here to kind of tweak that and get more resolution out of your converter. And so these would be these. That's just the output buffer. And then there is this neat trick that I read about in some article on the internet. And so the problem, of course, of those kind of DAC is the output noise, right? Because every time you switch your IO from low to high or something, you tend to generate an edge. And even with the smoothing of the capacitors, just a simple LC filter, it doesn't filter that much. No, because it's delta sigma, you try to push as much of your noise into the higher frequencies. But still, it's not perfect. And this AC couples the edges, but inverts them. This is the opposite of that bit, which means it's kind of an active noise cancellation, which actually works very well. So that's the test board that I used to test this. And I fed that to a Rodentschwarz spectrum analyzer. This is the noise output in a unipolar mode. So the two lower lines, inverted lines, are disabled. And this is the output with the active noise cancellation, which means there's one peak that's still above the noise flow of the analyzer, but that's it, which I found was for a couple of more resistor and one capacitor, that's worth it. Especially since one of the application I'm using this for is to tune VCXO. And so I want as clean as possible output, basically. Another application, kind of the same board, that's tracking the phase of GPS PPS. So I'm assuming most people are familiar with the, if you want to do a cheap GPS DO, you take any GPS receiver, you take the PPS output, you take a 10 megahertz oscillator that you can tune, and then between two PPS, you count how many 10 megahertz cycles you got. If you got more than 10 million, when then you tune your clock a little slower, if you get less, you tune it a little higher. But given it's based on the PPS, well, you get one pulse per second, which means you only get one measurement per second. And so if you want to achieve very fast transient response, but still good precision, you have a trade off there, because you get 10 million cycles every once a second, you can only get 100 ppb, kind of maximum error detection. So you need to average over a lot of time, and so your response is pretty slow. So one method to get more precise measurement is not only track the number of cycles you get, because hopefully you can get to 10 million exactly, but also track the phase of that PPS pulse versus your actual 10 megahertz clock. And that gives you more input to your tracking loop. And that's what this is designed to do. You basically get the timing diagram. But the general idea is that you take your 10 megahertz clock, you divide it by some number. I chose 8, because it's just easier to divide by 8 than 0.10, but it doesn't matter. And you track the phase of the PPS to that. And the way you do this is this flip flop is used as a phase comparator. And so when the PPS happens, since it's connected to the clock and the data is connected to 1, this output will become high. And it will start charging that capacitor slowly. Well, actually not that slowly, but it will start charging that capacitor. And when the next edge on that clock happens, which is what you're comparing the phase to, it will reset it. And so it will disable it. And so at that point, because those are inverted signal, the capacitor will start discharging. And so what you do is you have a discharge resistor, which is much higher than your charge resistor. And so that's basically a dual slope ADC. You charge a capacitor pretty quickly to convert a time interval into a voltage. And then you discharge it much more slowly so that you convert back that voltage into a time interval, but which is multiplied into a much longer time interval. And then that longer time interval, you can measure it using a counter and report that to the host to do your phase measurement basically. That's the board that does that. And so you get basically, I use the LP384 here, because it's the smallest size for the FPGA. That's the passives to do the dual slope ADC. And this is the perl density modulator represented before to control the O6O. And that's the I2C interface, basically, on those pins. That's the phase measurement. It's rather noisy, but those variations are actually a very, very small time interval when you scale them down. And so it's not really a problem. Like a variation of one cycle of the 10 megahertz would be much, much higher than this. And so even if it appears noisy, it's just because I'm using something I didn't present here. But to detect when the capacitor is fully discharged, this is a very low voltage, like 0.1 volts or something. And I'm using a differential input of the FPGA as a comparator, which is not really designed to do that. And because the voltage slowed down really slowly, the threshold isn't perfect. And so you get some noise, but in practice, it works fine. It doesn't matter. Something else I did with this FPGA is implement a full speed. USB is confusing. And because USB full speed is just CMOS 3.3 volt, right? They say it's differential, but in fact, it's just two independent IO that most of the time, you toggle them one against the other, but not all the time. And so the FPGA IO can drive that without an external phi. That's the structure of the core. So you get basically the FPGA IO. This layer deals with all the low level stuff of USB, and really, really low level, like things like bit stuffing and stuff like that to ensure the appropriate number of transition. Then you've got the layer that actually creates and receive actual packets. Then this goes up to this, which is the transaction layer. So if you know a little bit about USB, the transaction layer, you get a token from the host, and then you have to reply within six-bit time with a packet of your own. And then you're going to get another one. And that's what's called the transaction layer. But the response time is really fast. I guess it's six-bit time at 12 megabits. So that's not a lot of time. Not enough for CPU to respond. And so this is coded in logic. But to be fairly flexible and be able to do it easily, this is actually coded as a microcode state machine. So if you look in the source, you'll see actual opcodes, except those opcodes are really, really specific to USB. There is an opcode that says start the transmit of a packet or compare the length of a packet. That kind of stuff, really specific to USB. It only has seven different opcodes, I think. But it basically implements, if you look at the USB spec, you'll find state machine diagrams that implement the transaction. It basically implements that in microcode. And yeah, it has a transmit and receive buffers for the different endpoints compared to some code that you would find in a microcontroller. Because it's very similar to what you would find in an Atmel or something like that. It's basically what they call the SIE, the serial interface engine or something. The only difference is that usually in an SIE, you've got a fixed number of endpoints with fixed size buffer. This doesn't care. You can, I think you can have 16 endpoints in USB, I think. Yeah, is it 16 or 32? I don't remember. Whatever, I mean, if you want to. If you want to. Exactly, here, if you want to implement 16 endpoints in and 16 endpoints out, you can assign the buffer independently to whatever endpoints with whatever, either single buffered or developed buffered. And so if you want to implement like a 16 channel UART, you can do that with that. It doesn't matter. You have full flexibility there. If you want to implement control endpoint on something as than endpoint zero, you can also do that if you want. I'm not sure who you're going to talk to, but whatever. So some of the fun application quickly, MyPyDSI and talking to those iPod screens. That's a board to also talk to MyPyDSI, but larger size screens. I just, I sorted it not long ago. I haven't actually tested it. I haven't even flashed a bit stream to it yet. So I don't know if it works, but it's at least designed to do that. Yeah, driving LED panels. That's a re-implementation of a kind of old school text mode that you would find in Commodore 64 or stuff like that, which is a text mode, but with programmable glyphs and pallets and stuff like that, except it drives display at a 1080p resolution and a 60 frame per second. But it's text mode because I don't have the RAM to put a frame buffer on there. But you can still do fun stuff like re-implementing breakouts or simulating like a graphical output in text mode. Yeah, a few links to the documentation from Lattice. It's not always super clear, but at least it exists, right? The links to the tool chain, if you want to install it and start working with them. A couple of very interesting IC channels that I definitely recommend. And then a link to GitHub repo, where I basically put all my Ice 40 stuff. And that's it. Any questions? I know it was quite fast and quite, I mean, I just prepared a bunch of stuff. I just really wanted to show a few applications and tips you can do. But if you want to talk to me about any particular application or have more details or stuff like that, because yeah, I know it was just pictures and me talking over them basically, so yeah. We have a second microphone. Yeah, so how many pins are there on the package? So the package is 48 pins for the UltraPrix 5K. And I think you can use 38 of them as IOs. Some of them have some restriction. There's three IOs, which are kind of, they're meant to drive an RGB LED. So they are constant current sync, which you can actually program which current they run at. You can use them as normal IOs, but then they are open drain. And I saw some DSP blocks on the diagram. Yes, you have eight of them. Is that of any use like for Channelizer? Yes, I actually have, I didn't show it there, but I actually have a P-Mode with a SX 2057, which is a lower, it's meant as a lower transceiver, but really you get just IQ data. What's interesting about it is that you get one bit IQ data, just highly oversimpled one bit IQ data. And then for transmit, you have to use the delta sigma third order to generate that one bit IQ. And for the receive side, you basically take it, then I run it through CIC and then through an FIR filter to get lower bit rate, higher bit depth RF. And I'm planning to use the DSP block to implement FIR. So even SDR might be between the... Yeah, I mean, it's low rate SDR, but I'm actually, this could actually implement like a GSM transceiver technically, because that SX 2057 does run into the 900 megahertz band. And the only thing I'm missing is a 30.5 megahertz crystal or VCO, because that's kind of the only rate that I would have that would be convenient to have the 278.8 and 33 in GSM, whatever. Yeah, we have a clock generator. Yeah, so the clock generator, I'm waiting for it, yeah. Well, you can have one. Thank you.