[PK] is working on a very simple video card, meant to output 640×480 VGA with a cheap CPLD. The interface will be 5 Volt SPI, meaning there’s a ton of potential here for anyone wanting put a reasonable (and cheap) display in a microcontroller project. The project has come a long way, and his latest update showcases something that has only been done once before: color NTSC with programmable logic
The brains of the outfit is a $5, 100-pin CPLD from Xilinx. Apart from that, the rest of the components are a crystal, PLL, and an almost hilarious number of resistors for the R2R ladder. The one especially unique component is the 25.056815 MHz crystal – multiply by that by two, and it’s fast enough to drive a VGA monitor. Divide the crystal by seven, it’s the 3.579545 MHz you need for an NTSC colorburst frequency. That’s VGA and NTSC in a single programmable logic project, something the one FPGA project we could find that did color NTSC couldn’t manage.
The next step in the project is designing a PCB and figuring out the code for the framebuffer. [PK] put up a demo showing off both VGA and NTSC; you can check that out below.
The project featured in this post is an entry in The Hackaday Prize. Build something awesome and win a trip to space or hundreds of other prizes.
24 thoughts on “THP Entry: A CPLD Video Card With VGA And NTSC”
reminds me a little of this project, I don’t remember if it was on HaD or not: http://www.lucidscience.com/pro-vga%20video%20generator-1.aspx
“the one FPGA project we could find that did color NTSC couldn’t manage.”
Well, the Spartan-3A starter kit from Xilinx does it as well. So you could just grab the circuit and reference designs from there.
One of the demos actually is a Paint demo, with mouse interface and color VGA output. Another uses the onboard DDR2 for a much more serious demo.
However I don’t really see the usefulness of this. The CPLD doesn’t have enough resources to buffer any of the data (not even close), so you have to feed it the data at line rate. That’s a huge demand on whatever’s on the opposite side of the SPI interface.
If you’re just looking for the cheapest overall programmable solution, I think the answer is probably a Lattice iCE40. An iCE40 HX1K gets you a good amount of buffering (although still not enough for 640x480x8 bits!), and the PLL all rolled into one *also* for $5. (And you don’t need the PLL). Plus you can program the thing over the same SPI interface too.
I second the Lattice options although I would use an XO2 as it has a few more package options. Without internal block RAM to implement FIFOs, you have to run the memory interface in lock step with the clocking. That limits your windows of opportunity to update the SRAM to interleaving or VBI. And there just isn’t enough logic in a small CPLD to do that (small being 128 MCs). A small FPGA is better.
For similar FPGA project, look at Project VGA @ http://wacco.mveas.com/ Or if you just want a simple serial controlled VGA controller (defeats the point of your hack), look at the FT800 ‘EVE’ chip from FTDI.
Forgot… and XO2 is supported by Diamond which is the biggest reason to choose it over iCE40. Silicon Blue tools are just not as good. Lattice is working on adding Silicon Blue support to the next release of Diamond soon however.
I agree that the iCE40 tools are pretty bad – however for a tiny FPGA design like this, it just isn’t that big a deal. I can’t tell you how many little random goofy things there are in those tools…
The iCE40s have quite a few neat advantages over the XO2: they’re cheaper and generally have more resources in any case. They also have differential pair inputs, which isn’t important here, obviously, but makes them very multipurpose since you can use the differential inputs as an ADC. Packagewise they seem pretty similar, although I would *love* something like a 64-pin QFN FPGA with a PLL.
But in this case obviously it doesn’t really matter – either the XO2 or the iCE40 would be fine, and quite a bit better than a small CPLD.
Thanks Alan for the heads up on the FTDI FT800, I hadn’t seen that before. Unfortunately it’s 3.3 Volt.
I think [PK] has done a great job of getting VGA into a 144 Macro CPLD (XC95144XL). AND it is a 5 Volt Chip.
I have been looking ‘forever’ for a VGA like interface to use along side old retro CPU’s. Needs to be 5 Volt, simple, low pin count (preferably DIP adaptable), small addressing space, tile based (for low MIPS CPU’s) and have hardware scrolling at a res below the tile dimensions.
[PK]’s project here is perfect for what I want except the SPI which would be a burden for an old low MIPS CPU. So I am watching his project very closely and I will try the same on a 72 Macro (XC9572XL). Wish me luck lol.
My ‘plan b’ is to use an ATMEGA for VGA. That has been done many times now.
I am always happy to hear about alternates.
Actually, the XC9500XL series runs on 3.3V, but has 5V tolerant Inputs and 3.3V outputs.
I did a lot of searching for similar reasons and that’s the only series of 5V tolerant CPLD that are currently produced/supported.
Actually, IIRC there’s a way to make a 6502 CPU and 6522 VIA do SPI. *goes googling* Ah, here it is –> http://6502.org/users/andre/csa/spi/index.html
I know a friend of mine who’s using that trick for a project of his. I’m not spilling the beans on his thing, though! Not my story to tell ;)
Why not go for a 8-bit interface instead of SPI if you have a CPLD. That would improve the uP bandwidth. You would need something to store the data as the CPLD has no storage other than you can convert 1 macrocell per bit of storage. A dual port RAM may be useful for making tiles.
http://elm-chan.org/works/crtc/report.html “General purpose display controller”
It is a VGA interface using XC95108 and SRAM
SPI isn’t that bad to bitbang – but have you looked at 74HC595 / 74HC597 for a cheap hardware alternative? You could hang a ‘597 off an 8 bit wide bus and have that clock out your SPI signal.
How DIP adaptable are you looking – enough to barely fit on a breadboard or something smaller? The 100 pin, 7 power input XC95144XL makes “small” a bit difficult, but I don’t really have a final size in mind, so I wouldn’t mind a target to shoot for in a future version. With the ’72 you’ll probably have to compromise on the resolution (maybe 320×240?) – the ~20 bit counter for read and the ~19 bit counter for write in 640×480 quickly use up your macrocells, and you actually hit pterm limits pretty easily too with the “>” and “<" statements for Vsync/Hsync.
I might take another run at the '72 once I have this working – sounds like a nice challenge (and it's like 1/4 the price… weird).
At this stage I am looking at addressed video RAM and not SPI. To have DIP or perhaps a TQFP44 – 64 on a DIP adaptor would be good if it can be done but the main reason for DIP is for pin spacing and soldering. PLCC sockets are not that hard to solder so they may be ok as well.
I think 320×240 is a reasonable target but I was going to try and use tiled base graphics which isn’t RAM expensive so higher reses should be too hard.
The EVE is interesting- looks like they went down the color quality vs. resolution rabbit hole just like me (and picked better color). I’ll probably be using this for something like MAME, and 8 bit color is already overkill for most games (haha)… I just wanted the 640×480.
Too bad that other VGA project didn’t finish – looks like they haven’t updated since 2008. 200 Euros might be in my ‘double digit dollars’ target range nowadays.
You’re right – but looking at datasheets, I can’t find many cheaper FPGAs with 2.46 Mbits of block/distributed RAM. Looking around my place, the only one that can do it is the Artix-7 board (tons of Xilinx here) – but that one ironically has DRAM on it already, haha.
However, I’ve only got to buffer one pixel at a time – I’ll have an 8 bit output register and I’ll be hanging a 4 Mbit ISSI IS61LV5128AL-10 SRAM off it.
That PLL though – yeah, getting the clock in this project is annoying. I’d love to see a cheap CPLD/PLL combo.
Pretty much all vendors’ newer (as in non-5V tolerant) CPLD have FPGA type of resources i.e. PLL, RAM, FIFO etc. If you gone through those troubles, might as well use a real FPGA. Depending on the series, some even have non-volatile storage for their configuration.
You can always use a small-ish XC9500XL as a 5V – 3.3V level shifter / I/O interface and let a FPGA/CPLD do the VGA work. CPLD works out cheaper and more flexible than discrete 74LVC parts for conversion. (forget about resistors as they have problems even at these low speeds)
There are FPGA eval boards and some of them are cheap, so the messy part of routing/soldering fine pitch parts are done.
You’re not going to be able to buffer an entire frame. That’s just not doable without DRAM (although DRAM is pretty trivial to interface to – it would be easy to grab something like an old SIMM and use it for cheap RAM).
But you could buffer an entire *line* at a time, and that reduces the latency requirements on the microcontroller a ton – it makes a very simple interface, where you just have the FPGA assert an interrupt line every ~32 microseconds or so (at each HSYNC point), and the microcontroller then needs to feed it 640 new bytes of data sometime within the next 32 microseconds.
Better, you can buffer something like 4 lines at a time, to reduce latency/bandwidth requirements even more. Now you’re talking about getting around 2560 bytes of data every 128 microseconds. Which you might be able to do with an FTDI USB link with some effort.
Heck, you might be able to do it with a couple of SPI links, although obviously that’s a hefty processing demand on a microcontroller anyway.
(The FPGA could also receive data at a lower resolution/line rate and interpolate it, or some compression-like thing could be added to only do deltas from the previous line).
” I’d love to see a cheap CPLD/PLL combo.”
Like was said above, a Mach XO2 or a Lattice iCE40 HX both have an integrated PLL. In this project you really don’t want a CPLD. The only thing a CPLD gives you is guaranteed low pin-to-pin timing, as opposed to an FPGA which can have gigantic pin-to-pin logic timing due to routing through fabric. (This is why many old/small FPGAs contain “typical pin-to-pin timing” in their datasheets). And you don’t need that here, at all, because you have two different clock domains. There is no combinatorial path from one pin to another pin (or at least there doesn’t *need* to be.
I think a lot of people tend to think “CPLD = cheap & simple”, “FPGA = big and complex”, but that’s very artificial. FPGAs are architecturally very different than CPLDs, and there are FPGAs that are smaller and cheaper than CPLDs. The two kinds of programmable logic serve very different roles.
I’ll admit that some of the reason for picking a CPLD was the novelty, and having to work inside the limited resources of the 144 macrocells… otherwise I’d find a non-BGA package and switch it up. I’ve actually been running into pterm limits before flip flop limits.
I’ve got a fair number of FPGAs that can do VGA just fine, including an Artix-7… which is a beast. (haven’t attempted NTSC on any, but if the 64 macrocell part can do it, I’m sure it’s just spending the time to wire it).
You may have missed it (stuck in one of the above threads), but I’ll be using a 4 MBit 100 MHz SRAM from ISSI as my frame buffer.
As for speeds, anything reasonably modern can handle VGA – I’ll be clocking this at around pixel clock * 2 (XC9500 series doesn’t have dual edge flip flops), so really anything that can handle 50.35 MHz would suffice.
I once wrote a FPGA text mode VGA output module:
I don’t understand the 3.3V/5V requirement. Use a more common 3.3V programmable device and level translate the inputs with a quick switch or 74lvc245 (can even get those in DIP!). You are not going to create much more than a simple pattern generator with <100 macrocells and no block RAM.
Also one correction on the iCE40. You only get hardened peripherals on the Ultra which isn't available from common distributes yet and will likely be a comparable price to the XO2. XO2 is available now from 256 to 7K LUTs, up to 2 PLLs, hard SPI, hard I2C x2, and plenty of block RAM for buffering. Spartan 3/6 and Cyclone 3/4 are also good choices for this project.
They’re available in the iCE40 LM series, although only in BGA (although a 36-ball BGA would be pretty easy to place by hand). But an SPI interface is pretty damn trivial to implement in fabric. It’s just a shift register, after all.
Fabric implementations would be much faster, too. The XO2/iCE40 LM’s SPI core is limited to 45 MHz. Fabric can run significantly faster.
Any of the major vendor FPGAs (Xilinx/Altera) would be significantly more expensive (4-5 times in the case of a recent generation part, 1.5-2 times in the case of an older generation part).
Thanks Alan, and I hope you’ll follow along – I’ve already posted my SPI implementation if you’d like to take a look: https://github.com/dqydj/VGAtonic/blob/master/SPI_Demo/SPISlave.vhd
The final part is going to be the 144 Macrocell XC95144XL, with a 4 MBit SRAM attached. One of my targets is the Intel Galileo board, which can do 25 MHz SPI, so I’m trying to leave myself some extra headroom if I find other, faster SPI speed devices to attach to this.
Cpld are a possibility, or you could use dma and the timers of a modern mcu for cheaper since you will need the command anyway. NTSC also has been done. What I’m looking for is a way to generate hdmi but this is out of reach of current MCUs … Until a wizard does it !640×480 is after all a standard res for hdmi.
VGA (640×480@60 Hz) 25 MHz 250 Mb/s 24 bits
So you want to generate 4 TDMS (R/G/B + clock) serial each with 250Mbps data rate output from a modern MCU timer/DMA!? That’s just the data encoding to have the parallel data serialized for DVI which HDMI supports.
On a SoC, that’s done with hardware. e.g. RPi.
You don’t need to output a full 24 bits from the MCU (heck you don’t have to output 640×480). Let the FPGA (a CPLD for HDMI is just stupid) interpolate it up.
Doable in one of the cheapo FPGAs, I think, but you’d probably want a Spartan-6 to gain the high-speed deserialization.
If you are going down that path, ditch the microcontroller/processor and embed it inside the FPGA. Much less wiring things together. Just a FPGA development board in the double digit price range comes with external memory. Video output can be level converted to 3.3V CML if you want to be electrical compatible with DVI/HDMI. Or use resistors as video DACs if you want old VGA.
Please be kind and respectful to help make the comments section excellent. (Comment Policy)