I was intrigued by Bill's recent posts on CPLDs, and a few weeks ago I came across this developer board based on Altera's Max II. It was so inexpensive—I think I ended up paying $10 CAD shipped for mine—that I figured it wouldn't hurt to try and see what could be done with it, and so I ordered one. It arrived after a few weeks, but I was busy with work, and didn't really get around to trying it until last weekend.
I had no idea to expect (and really no expectations that I would be able to do anything useful with a $2 chip), but I was surprised to find out how much capability can be squeezed out of these devices. In particular, I was surprised by how much more quickly one can prototype a circuit, especially using Verilog. Once you get past the fact that it looks like C but doesn't quite behave like it, it's remarkably easy to build what circuits that would be pretty complex (at least for me) implemented using only discrete logic.
In any case, I started with blinking a LED, and somehow ended up implementing the VGA controller that I've always wanted for my SBC
- Completely asynchronous operation; you should be able to just bitbang data into the registers at the typical speeds supported by most hobbyist projects.
- 320x240 resolution at 8BPP (RRRGGGBB), rendered as a 640x480 @ 60Hz standard VGA signal.
- 640x240 resolution at 4BPP “high res” mode using a CGA-like palette, capable of 80x30 text (though you will have to implement the text rendering in software).
- Hardware accelerated vertical scrolling (handy for text displays).
- Toggable self-incrementing X coordinate for faster data transfers.
- Active-low interrupt when entering the non-visible area at the bottom of the screen.
I put the entire source up on Github in case this comes in handy to anyone. The Max II is technically obsolete, but easily obtainable from AliExpress, even with all the FPGA/CPLD shortage going on, and it costs a pittance. The design leaves enough resources unused (about 15%, and roughly 20 pins) that it should be possible to use the extra room for glue logic or other applications to reduce the chip count in an SBC design.
To wit, I have ordered some PCBs from JLCPCB; the design ends up being small enough that I was able to splurge on a 4-layer board, so I'm looking forward to seeing how well that works when it gets here. In the meantime, I have built an even-worse-than-usual rats' nest using the development board:
I would love feedback on the design—I'm sure there are plenty of ways to improve it (and probably a few bugs). In particular, I couldn't get the MPU interface to work bidirectionally… if I add functionality to expose data through the bus, the CPLD always ends up picking up a bunch of garbage when a write occurs, even though I wait a full clock cycle for the signals to stabilize. This doesn't matter too much—I don't really need the read functionality at this point, but it nags me that I can't understand what I'm doing wrong, and I suspect that I may one day want to add the ability to send data back to the MPU anyway.
The interface really does all I wanted for my SBC; in particular, I was keen on supporting 80x30 text with good scrolling performance, which I was able to achieve by using a hardware offset, so I think I'm going to stop here and focus on interfacing with my computer instead. In the future, I am keen to add some more fun functionality, like sprites and proper text-mode support, but for that I will most definitely need a more powerful CPLD (possibly with built-in memory, because interfacing with an external chip was not easy). I welcome ideas for more features!
A big thank-you to Bill for piquing my interest with his posts; I also borrowed liberally from this old post by Arlet when coding the memory interface, so big thanks to them and the other on that thread as well.
Cheers,
Marco
PS: If anyone knows of a good looking 8x8 font that I can use, I would be very grateful for a pointer to it. Though I am happy that I was able to find a free one to use, it doesn't look great in either 40- or 80-column mode!