Modern Circuit Design ##################### .. include:: /header.inc .. vim:filetype=rst spell: Back in the dawn of time, when electronics was a new technology, designers spent hours wiring up circuits and testing them with a variety of expensive test tools: .. image:: images/workbench.jpg :align: center :width: 600 I have a friend who had a bench like this in his basement. He and I built our first computers from parts we scavenged from old electronic gizmos we bought in surplus stores, just for the parts! When digital circuits first arrived, the parts got much smaller, and you could get sockets to plug them onto a board. Then your job was to wire the pins together to make up your gadget. Unfortunately, with lots of parts, the wiring got very messy! .. image:: images/wiring1.jpg :align: center :width: 600 You could buy all the gear needed to do this at your local Radio Shack (remember those?) To build something like this, you needed lots of wire, a stripping tool to peel away the plastic coating on the wire, and a soldering iron and solder to fuse the wires to the pins on the sockets where each part would live. Tedious work to say the least. A revolution occurred when someone thought up a way to make a connection to a pin without using solder. Wire-wrap technology looked like this: .. image:: images/wire-wrap-pin.png :align: center :width: 300 Suddenly, things got a bit easier. But boards also got bigger, and this was the result: .. image:: images/wire-wrap-board.png :align: center :width: 600 Your eyes went cross-eyed trying to follow each wire to make sure your circuit was wired correctly. Blue-Flame Testing ****************** Once your design was finished, you hooked it up to a power supply and fired it up! You watched carefully to make sure you saw no flames or smoke rising up from anywhere. This was called the "blue-flame test". Something like this: .. image:: images/blue-flame-test.jpg :align: center :width: 600 Well, not really, that is an Arduino_ board hooked up to a temperature sensor, looking for the heat from a yellow flame. Occasionally, when our boards were a mess, we would want to set fire to them, on purpose! Digital Circuit Design ********************** George Boole's Algebra helped in working out the design. Suppose you want to build a Multiplexor, used to route signals . A four-to-one multiplexor would have four input signals, a selector, and one output signal. Setting the selector picks one of those four inputs and sends it along to the output. You could build one of those using our parts kit in a snap. We can label our inputs as ``A``,``B``,``C``, and ``D``, and label the output ``Q``. Since there are four of them, we need two input signals to identify which one we want. Call those inputs ``a`` and ``b``. Here is the Boolean expression we would need for our circuit: .. math:: Q = \overline{ab}A + a\overline{b}B + \overline{a}C + abD We can build this entire thing using just simple NAND gates (an AND with an inverter GATE on the output end). Here is the required circuit: .. image:: images/4-to-1-mux.png :align: center :width: 600 That is a lot of parts. Fortunately, we could buy small DIP packages with four NAND gates in a single part. Still we had a lot of wiring to do! Programmable Arrays of Gates **************************** Another revolution occurred when someone, staring at that figure up above, noticed that we were spending a lot of time wiring up something that basically implemented that truth table in the diagram. What if we could simply build such a table in a memory component, load the table with the right bits, then simple "look up" the right answer. No ugly circuit was required. This led to the development of the "Field Programmable Gate Array" (FPGA) .. image:: images/fpga.jpg :align: center :width: 600 This cool idea has led to the production of a bunch of boards suitable for designing and testing real digital parts. Here is one of mine: .. image:: images/tinyfpga.png :align: center :width: 300 .. _TinyFPGA: https://www.eeweb.com/profile/duane-benson-2/articles/a-look-at-tinyfpga-boards This TinyFPGA_ board is available form SparkFun_ for around $38. IT has the following features: * 7680 4-input look-up tables * 128KB block RAM * 8MB Flash memory * 41 user I/O pins * Program over USB with Python tools Along with the development of tools like this, it also occurred to designers that setting up these gadgets could be done in software, and no more wiring was required. Suddenly software development skills could land you a job in the hardware world! Language designers came up with "Hardware Description Languages" that looked and felt much like the normal programming languages in use by software developers. There are many such languages around, but two stand out: * VHDL * Verilog Of these, I prefer Verilog_, since it is more closely related to C/C++ programming. Let's take a peek at Verilog_: Installing Verilog ****************** I am going to show you some examples of modern hardware design using the Verilog_ HDL language. There is a nice open-source tool called `Icarus Verilog`_ available for this language, and it is available for all platforms. We will use a companion tool, GTKwave, to visualize signals moving around in our design. Installing it is easy on the Mac: .. code-block:: bash $ brew install iverilog $ brew install gtkwave On your Linux system, do this: .. code-block:: bash $ sudo apt-get install iverilog $ sudo apt-get install gtkwave Hello Verilog ************* We will not be learning this language in detail, but I will show you enough to use it to prototype some of the parts we need for our simulator. To get started, we need to write the classic "Hello, World" program in Verilog_. This is pretty easy: .. literalinclude:: code/ex01/hello.v :linenos: :language: verilog :caption: hello.v Now, this code has nothing to do with hardware design, but it does demonstrate how we can make our design generate output to help see what is going on. Plus it satisfies those programming gods who demand that you create a "Hello, World" project in any new language you meet! Here is a sample run of this program: .. command-output:: iverilog -o test hello.v :cwd: code/ex01 .. command-output:: vvp test :cwd: code/ex01 There! We have done it! Now we can move on to more interesting examples. Designing a Counter ******************* Something more useful to explore is a simple counter circuit. Here is a block diagram of the part we want: .. circuits:: :width: 300 :align: center \draw [fill=green!30] (0,0) -- (2,0) -- (2,2) -- (0,2) -- cycle; \draw (0.825,0) -- (1,0.25) -- (1.125, 0); \node at (-1,0.5) (res) {reset}; \node at (-1.0,1.5) (en) {en}; \draw (res) -- (0,0.5); \draw (en) -- (0,1.5); \node at (1,-1) (clk) {clk}; \draw (clk) -- (1,0); \node at (3,1) (out) {out}; \draw (out) -- (2,1); We will provide this counter with a 4-bit internal register that increments on every clock tick. Obviously, it will "roll over" and return to zero once we hit 15 ticks. The "enable" signal will be used to stop incrementing, and the ``reset`` signal will return the counter to zero. Here is the code: .. literalinclude:: code/ex02/counter_4b.v :linenos: :caption: counter.v And the output: .. command-output:: iverilog -o test counter_4b.v :cwd: code/ex02 As it stands now, there will be no output if we run this code. The right way to check the functioning of our component is to wire it up into a test fixture and exercise it. This is not as nice as using Catch_ for C++ testing, but this is how things are done. Here is the test code: .. literalinclude:: code/ex02/counter_tb.v :linenos: :caption: counter_tb.v The block of code labeled "initial" is how we set up the system. This assigns initial values to all of our wires and registers. It also sets up timing data used to change various signals ever so many simulation clock ticks. Running this gives this result: .. command-output:: iverilog -o test counter_4b.v counter_tb.v :cwd: code/ex02 .. command-output:: vvp test :cwd: code/ex02 This output can be studied together with the test code to see what is happening. The notation used to set up timing of the signals from the test bench is a bit convoluted, but here is what is happening. Basically, there is a master simulation clock running when we start a Verilog_ program. We set up our ``clock`` signal so it changes state every five simulation ticks. The ``$monitor`` statement tells the code to generate an output line any time one of the indicated signals changes value. We set the initial values for all signals (except ``count``) in the ``initial`` block, then start generating signal changes as follows: * time = 5, set reset to 1 * time = 15, set reset to 0 * time = 20, set enable to 1 * time = 120, set enable t- 0 * time = 120, stop simulation The ``#nn`` is the delay before this action happens. If you look at the counter code, you will see a ``#``` before the code that changes the ``count`` value``. That means that one tick after either the ``reset`` or ``enable`` signals change, we update the count signal. Does the output make sense? A bit of study will convince you that it is correct. Visualizing the Signals *********************** Verilog_ supports generating VCD_ files (Value Change Dump), which can be displayed on ``gtkwave``. Here is a modified version of the code that generates the VCD_ file, and also displays the output as before. I needed to move things around so the VCD_ file got generated. Here is what GTKwave displayed: .. image:: images/counter_4b_vcd.png :width: 600 :align: center This is more like what hardware folks are used to seeing. The cool thing is everything was done n software. We wired up no physical parts, but we see the system running as though it was a real thing! SimpleCPU ********* In doing some research on how instructors use Verilog_ in classes, I found this code from Swarthmore College Digitsl Design course page: .. literalinclude:: code/ex07/SimpleCPU.v :linenos: :caption: SimpleCPU.v I am working on this code to clean it up a bit for further study. Here is the processor this code implements: .. image:: images/SimpleCPU.png :align: center :width: 600 Obviously, this is not the same machine we are building. but based on what oyu know now, you should be able to see how it works!