I'm going to make some basic assumptions: that you vaguely know a language with C like syntax and have a vague idea that digital electronics is about manipulating binary data represented in wires by a voltage level using logic gates.
You can't design your own components completely from the ground up at home, for that you do need a lot of expensive equipment. But what you can do is program what are known as Field Programmable Gate Arrays (FPGAs) or Complex Programmable Logic Devices (CPLDs). These are large arrays of logic gates connected by a complex network that allows you to connect any gate to any other pretty much however you want. In effect you design a logic circuit on a PC that is downloaded to a chip. You can use all the usual digital components that you expect to see as discrete components: adders, flip-flops, shifters and so on. Even better, you don't even have to get your hands dirty designing circuits with these things because you can implicitly design your circuit with a high level language and have it automatically turned into a downloadable circuit.
Now here's a caveat: I'm not in any way an expert at this subject. I have no electronics background and my knowledge comes from a few hours of tinkering here and there in the evening. But I'm hoping that even though this means I'll make lots of mistakes I'll at least be able to demonstrate that this stuff really isn't that esoteric and that anyone who has basic programming knowledge can turn their hands to it.
There are a number of FPGA and CPLD development boards available but the one I'm going to talk about in this example is the Digilent XCR.
These boards use components from the company Xilinx and they provide a free development system known as Webpack. You simply plug the board in into a PC, fire up the development system, and go.
Now comes the design bit. There are two popular high level languages used for digital design: VHDL and Verilog. To my inexpert eye there is no difference betwen them except for the parser at the front end. Verilog looks like C and VHDL looks like Ada and requires developers to write a morass of syntactic glue that apparently serves no purpose. So I'll talk about Verilog. In fact, here's some sample code for you to look at. This code can be synthesized (that's like compilation but it's not called that) and downloaded directly to the XCR board with the free Webpack software.
So cast your eyes over some sample Verilog code:
module xcrdemo(mclk,ld9,btn,swt,led,an,ssg);
input mclk;
output ld9;
input [3:0] btn;
input [7:0] swt;
output [7:0] led;
output [1:0] an;
output [6:0] ssg;
reg [2:0] clkdiv;
reg [3:0] cntr;
wire cclk;
wire [6:0] dig;
assign led = swt;
assign ld9 = btn[2] | btn[3];
assign an = btn[1:0];
assign ssg = dig;
assign dig = cntr=='b0000 ? 'b0111111 :
cntr=='b0001 ? 'b0000110 :
cntr=='b0010 ? 'b1011011 :
cntr=='b0011 ? 'b1001111 :
cntr=='b0100 ? 'b1100110 :
cntr=='b0101 ? 'b1101101 :
cntr=='b0110 ? 'b1111101 :
cntr=='b0111 ? 'b0000111 :
cntr=='b1000 ? 'b1111111 :
cntr=='b1001 ? 'b1101111 :
0;
always @(posedge mclk)
begin
clkdiv<= clkdiv+1;
end
assign cclk = clkdiv[2];
always @(posedge cclk)
begin
cntr<= cntr+1;
end
endmodule
Chances are you can already guess what most of this does. I have defined a module (in this case representing the CPLD chip on the board) and I've defined a bunch of inputs and outputs. You can probably guess which is which. The brackets are used to declare arrays. For example out [7:0] led;
line tells you that led
in fact represents 8 output wires coming out of the CPLD. Unlike software engineers hardware engineers like to think of arrays backwards, hence the decreasing range from 7 to 0. The wire
lines define internal wires within the CPLD. They are used, as you might expect, to connect things to each other.
On the XCR the 8 swt
inputs are connected to switches and the 8 led outputs connect to LEDs. So assign led = swt
simply says that the state of the LEDs is equal to the state of the switches. In other words, each switch turns an LED on or off.
The assign dig
line is more interesting. If you can read C you'll guess immediately that it maps 4 bit numbers to 7 bit numbers. ('b means that a binary number follows) In fact the 7 bit ssg output is connected to the 7 segments of an LED display and this line performs binary to seven-segment conversion.
An important thing to note about the assign
lines is that they are continuous assignments. In C if you say a=b;
it means "copy the contents of b into a". In Verilog it's more like a functional language and assign a=b;
means "forever more the value of a is the same as the value of b". Every one of these assign statements is running simultaneously in parallel. That might give you a clue why you might want to use these devices rather than microcontrollers for certain situations - you can have all those adders, shifters and flip flops working in parallel unlike the traditional von Neumann type machines we normally use that only perform one or two instructions at a time. Imagine how fast you can run the game of life with a bunch of logic gates dedicated to every cell.
And that now brings us to sequential logic. What happens if you want your custom designed chip to perform things sequentially? That's where the always
line comes in. always @(posedge mclk)
means "whenever the value of mclk goes from 0 to 1 do the following". On the XCR board the mclk input is connected to a clock with a period adjustable from a few Hz to a few KHz.
Note how clkdiv
was defined to be a reg
instead of a wire
. This means that it is a register that has a persistent state. This means that when clkdiv <= clkdiv+1
is executed (once per clock pulse) this 3 bit register is incremented - it's more like a C assignment. Similarly the register cntr
is incremented every time bit 2 of clkdiv
goes from 0 to 1.
There are some other lines in the code and you can try to guess what they do.
So among other things this board displays a 4 bit count incrementing over time, though it remains blank for 0xA to 0xF. The CPLD device on the XCR board is non-volatile. This means you can simply pop it out of its socket and add it to your own circuits. Just connect up power and ground and it'll do just what your Verilog code says.
With my XCR board I have implemented a complete an entire CPU with memory in about 50 lines of code and on their DXL board I have made my own Pong game that plugs straight into a monitor with the FPGA directly controlling the voltage levels of the VGA in. This stuff is surprisingly straightforward and you get to learn a lot about how electronic devices really work at a low level.
So there you have it in a nutshell - digital design through Verilog. I'll just add one more thing about the code: to completely define how this code maps to the hardware there is another file that simply lists which pins on the chip correspond to which of the named input and output ports. The syntax is usually easy to decode once you've seen the example that comes with whichever board you decide to purchase. So go and get designing already! Even if you don't make a career of it or make a useful device for the home you'll have a deeper appreciation of just what exactly is happening inside your PC at any moment.
Further Information
There is a wealth of low cost development boards out there. Besides the Digilent boards you might like to try:
- The FPGAProto which comes with the verilog source to turn it into a complee 16 bit CPU. You can then hack the verilog to add your own instructions or custom I/O circuitry.
- The Pluto board.
- The BurchED.
- And a variety of boards are always available on Ebay.
There are many digital designs out there on the web. Example projects out there (some downloadable to synthesize on your own hardware) include:
- Atari 2600 on a chip.
- Various arcade games.
- Chess!
- Cracking DES
- A wealth of CPUs and computer hardware at at opencores.
- And the ubiquitous Pong game.
PS You don't have to use real hardware. Simulators for Verilog and VHDL exist. I've played a little with Icarus Verilog. The free commercial packages such as Webpack also come with (crippled) simulators. Watch out with simulators though - they allow you to write code at an abstract level that can be simulated but not immediately implemented in hardware. In effect Verilog doesn't just give a way to describe circuits but it also allows you to write code to simulate a circuit whose actual implementation you haven't figured out yet.
PPS One last thing: whenever I edit this story scoop incorrectly converts < in the source back to <. Sorry if it's messed up.