It’s vacation time - I’m having fun doodling with logic devices and gate arrays… have been messing about with them before, when duplicating Grant Searle’s neat Z80 setup.
This time I want to write some code myself. There are zillions of FPGA boards, so here’s what I’ve narrowed it down to:
From left to right:
MAX II CPLD - with 240 logic elements (LEs), 1K of flash memory, and 80 I/O pins - this eBay board is $7, but you also need this $3 USB Blaster to program it
Cyclone IV FPGA - 6,272 LEs, 30K block RAM - $26 on eBay, again needs an external USB Blaster - board includes a serial-USB interface and 8 LEDs
another Cyclone IV (same 6,272 LEs and 30K BRAM) - $45 on eBay, but with USB Blaster built-in, and lots of goodies on board: 32 MB SDRAM, 7-segment LEDs, VGA, PS2, 12-bit ADC, 2 PMOD headers
for larger designs, there’s the DE0-Nano from Terasic ($79 + shipping) - it has a beefier Cyclone IV (22,320 LE’s w/ 66K BRAM), 32 MB SDRAM, and more
All of these need a (free-but-proprietary) toolchain, i.e. Altera’s Quartus Prime Lite. I’ve set up an Ubuntu 14.04 LTS VM, which makes it fairly easy to use, even on my Mac.
Cyclone II boards (e.g. the EP2C5 used for the Z80) can be had for $16, but these only work with the older Quartus II (v13.0sp1).
The other major supplier is Xilinx. Both of the older Spartan-3 and Spartan-6 chips need an obsolete toolchain (ISE v14.7), only big/pricey chips can use the latest release (Vivado v2016.2). Also, programming w/ ISE from Linux leads to USB-driver-hell, so I picked Altera (which is now part of Intel).
The first thing I wanted to try is a blinking LED on the CPLD, the smallest device - just to see how it works. Here’s the Verilog code:
module blink (input clk, output led);
reg [31:0] count;
always @(posedge clk) count <= count + 1;
assign led = count[23];
endmodule
It divides the 50 MHz clock and ties the 24th bit to an LED, which then ends up blinking at around 3 Hz. The toolchain takes some getting used to, but all I had to do was define the pins to use, and get the USB programmer working from inside the VM.
Whee - that was easy!
Let’s up the ante a bit. Here is a slightly more interesting 6-bit Gray code counter:
module blink (
input clk,
output led, led1, led2, led3, led4, led5, led6
);
reg [31:0] count;
always @(posedge clk) count <= count + 1;
assign led = count[23];
assign led1 = count[24] ^ count[25];
assign led2 = count[25] ^ count[26];
assign led3 = count[26] ^ count[27];
assign led4 = count[27] ^ count[28];
assign led5 = count[28] ^ count[29];
assign led6 = count[29];
endmodule
Very similar, but now we tie 6 more LEDs to the XORs of adjacent bits in a slightly larger counter. Gray code is a way of counting in binary, whereby each count only changes one LED at a time. This uses a mere 35 LEs.
After adjusting the chip type and I/O pins, it runs on all the boards listed above.
Here’s a 20-sec video of the code in action.
I rather like that 3rd FPGA “learning board” with all the on-board goodies. It requires a single USB cable for power + programming, and there’s plenty on there to play with!