I am a hobbyist electronics fan and in my spare time, I make small pieces of equipment which help me with my daily life. An example, as of pretty recent, was using something called a Field Programmable Gate Array (or FPGA, for short) to build a 4 DoF drone.
Many of you might be aware of something called the Arduino. It's a pretty common piece of hardware used for prototyping and the language is pretty simple to use as well. However, sometimes, that just doesn't cut it. With an FPGA, you have the option of creating your own Arduino with whatever features you like; you can have 100 digital IO pins (depending on the part number of your FPGA, of course).
Now, FPGA's are also programmable. However, where they differ is what you are programming. With the Arduino (or more precisely, the ATMega family of IC's), you program logic and tell the chip what to do. With an FPGA, you tell it how to do what it should. For example, you can say tell the Arduino: switch the LED one, wait for 1s, switch it off, wait for 1s, loop. With the FPGA, you tell it something like: if the drain source is > 0V (it's in the logical ON position), send a signal to this wire; measure the current clock cycle and on the raising edge of the n-th cycle, break the loop. So, you are telling the FPGA how to switch the light on and off.
The series of gates thus generated form something called an Application Specific Integrated Circuit or ASIC (like the one used on bitcoin mining).
The Arduino uses something called the Arduino programming language which is an extension of Java along with C/C++. The obscure language here is the one used for FPGA: HDL or Hardware Description Language. Now, that's the category (much like high-level and low-level programming languages); we have two choices here: Verilog (language 1) or VHDL. I use verilog, so let's see an example (
not sure if syntax highlighting is supported xD who knew, it is!)
module dip_counter ( clock, enable, reset, o_counter );
These are the ports: or a collection of both input and output channels. We later define the inputs and the outputs:
input clock; input enable; input reset;
Now, we get to the interesting part: outputs.
output [3:0] o_counter;
[3:0] notation signified that the
o_counter output is a 4 bit output type. So, we will use four pins (in some basic designs) for it's output (+ common ground).
Now, let's define the
types of the input and output. Till now, we have only told the compiler what all we want; now we need to tell it how to parse or represent the data.
wire clock; wire enable; wire reset;
We have two types of elements:
reg. You can imagine
wire as a (pretty bad) stream: they can't store data but they can stream it and hence they are continuously reassigned.
reg on the other hand is like a register, it stores the value which you can later read/write.
reg [3:0] o_counter;
Now, let's get into the main logic (or the block):
always @ (posedge clock) begin: OCOUNTER if ( reset == 1'b1 ) begin o_counter <= #1 4'b0000; end else if ( enable == 1'b1 ) begin o_counter <= #1 counter_out + 1; end end
So, this cryptic code tells the FPGA to execute the block only when the clock edge is rising (positive electrical gradient). The
if blocks check if the reset pin is high
1'b1 means HIGH and
1'b0 means low. If it is high, then reset the counter. Else, increment it.
b0000 means 4 bits and so on.
This is a pretty simple example which I guess I got off the internet (I had it on my laptop when I got my first FPGA kit) and I tried to explain as much as I could; however, since this is used for hardware definition, you can't see anything till you either get the FPGA itself and program it; or, download the Verilog IDE and run a simulation.
Well, this is, by far, the most esoteric language I have ever encountered. What do you think? xD