FPGAs are pretty awesome. But what are they, and how do you use one? Search no further than here!
|A Cyclone III FPGA chip on an Altera DE0 dev|
board, up close.
An FPGA is kind of like a CPU, but more awesome. Just like you can reprogram a CPU to do different things, you can reprogram an FPGA to be different things. In other words, you are given a whole bunch of logic gates and the complete freedom to hook them up however you want. Think about that for a moment.
That's the awesomeness of FPGAs.
You can make audio processors, password crackers, Bitcoin miners, and even parallelizable GPUs and CPUs - all on an FPGA.
The question is, how?
Just like a CPU is programmed with a number of different special languages, an FPGA is also programmed with a kind of special language - a Hardware Description Language, or HDL for short. Unlike a procedural language like Python, C or Java, an HDL tells the FPGA how to hook up its logic gates.
This means that, more often than not, a bunch of things are happening at the same exact time, and that, primarily, is what FPGAs are good at. When learning to program FPGAs, you will be learning to think in parallel, and that is a powerful thing. FEEL THE POWER!!!
There are two main HDLs out there: Verilog, and VHDL. Because Verilog is the first language I learned, and it is less verbose than VHDL, I'll talk about that. First, look at the commented code below.
module FPGA_TOP( input CLOCK, // from the hardware clock generator output [7:0] GPIO_LED // blinky lights! ); // ### DECLARATIONS ### reg [7:0] count; // 8 bits // ### LOGIC ### /* Continuous assignment; the wire GPIO_LED is driven by * count, no matter what else is happening. */ assign GPIO_LED = count; /* The stuff in this always block happens on the rising clock edge. * Thus the funny <= assignment operator below; above was * a continuous assignment. Here, it's an edge-triggered * assignment. Why? BECAUSE THIS IS NOT C. Above, we were driving a * wire. Here, we are clocking data into a register. */ always @(posedge CLOCK) begin count <= count+1; end // always @(posedge CLOCK) endmodule
What do you think this does? It counts in binary using the 8 LEDs on the dev board. Some things to notice about this code:
- It begins with
module MODULE_NAME(...);and ends with
- You must declare the size of your regs and wires, or they will be one bit wide. (You can do some pretty wacky stuff, like making a 39-bit CPU, similar to what NASA did 50 years ago!)
beginto begin blocks, and
endto end them. Makes sense, no?
- It looks a lot like C. BUT IT'S NOT! THIS IS NOT C! THIS IS PARALLEL, DUDE! C IS PROCEDURAL! VERILOG IS AWESOMER!!!
|The Verilog code, translated into circuits.|
Logisim is great.
Note the CLOCK signal in the diagram and in the Verilog. Things only change on the rising edge of CLOCK; even if the CLOCK stays high, there will only be one change until the clock goes low and goes high a second time. That is why we use
always @(posedge CLOCK)in our Verilog. We could have put the code in an
always @(*)instead without waiting for the CLOCK edge, but then the count would increment over and over again very fast and without control. In the diagram, this would be the same as removing the count register and connecting the input and output of the +1 block together.
So, registers are like locks in a canal; they hold data still until ready to be changed.
How did you like your first taste of Verilog? Please leave a comment if you are interested in more; I'll write more about it.