HDL – Full Adder Schematic

This is a continuation of my FPGA series.  I’m going to show how to create a one-bit full adder circuit using a schematic diagram in Xilinx HDL language.  Then I’m going to send the compiled code to the Mimas V2 Spartan-6 board and test it.  This project is for the entry-level FPGA programmer.  If you just purchased the Mimas V2 board and you’re unsure how to get started, this short tutorial should help with some of the entry-level basics.

To start this project, you’ll need to download and install the Xilinx Design Suite by clicking here.  Follow the instructions, you’ll need to register and answer some questions and install the software.  Go to “All Programs -> Xilinx Design Tools -> ISE Design Suite 14.7 -> ISE Design Tools -> 64-Bit Project Navigator”, then click on the “New Project” button.  If you’ve already installed the tools and wish to start a new project, you’ll need to go to the File menu and close the project before starting a new project.

When the new project dialog starts, select “Schematic” as your top level project (I keep my FPGA projects in a directory on my D: drive):

Then give your project a name and click on the next button.  Then click next again.

You’ll need to create a schematic. Right click on the FPGA board designation node and select New Source:

Click on “Schematic” and Next, Next.

Now you can draw a schematic.  First you’ll need to find logic gates that you want to use.  If you click on the “Symbols” tab (bottom tab of the palette window):

You can find logic gates like and2 which is the 2-input AND gate.  Draw a full adder circuit.  The basic logic for a full adder is like this:

You can plot the XOR2, OR2 and AND2 gates first, then use the wire tool to connect outputs to inputs.  Next you’ll need to add connectors to the A, B, Cin, S and Cout points.  Your final circuit should look something like this:

I added three VCC connections to the enable pins of the LED displays since I won’t be using them. I also had to invert the outputs because the LEDs on the Mimas board are active low.  You can use an XNOR gate instead of an XOR and inverter and you can use a NOR gate instead of the OR and inverter.  I added inverters after I generated the code, sent it to the board and discovered that the LEDs lit opposite of what I expected.

The connectors (A, B, CARRY_IN, SUM, CARRY_OUT, EN1, EN2 and EN3 in the diagram above) can be added from the palette to indicate inputs and outputs.  You’ll need to give them a useful name so you can designate a physical pin to connect them to.  Double-click on the connector object and you’ll see this screen:

Now click on the name under the “Nets” branch and then change the “Name” to the value that you want.  You can also change the connector to be an input or output.

To define the connectors to a physical pin, you’ll need to add a ucf file to your project.  Right-click on the FPGA node again (under the Design tab) and add a New Source.  This time select an Implementation Constraints File:

Then add the following definitions to connect the circuit to your FPGA board:

NET "SUM" LOC = P15;
NET "CARRY_OUT" LOC = P16;

NET "A" PULLUP;
NET "B" PULLUP;
NET "CARRY_IN" PULLUP;
NET "EN1" PULLUP;
NET "EN2" PULLUP;
NET "EN3" PULLUP;

NET "A" LOC = F17;
NET "B" LOC = F18;
NET "CARRY_IN" LOC = E16;

NET "EN1" LOC = B3;
NET "EN2" LOC = A2;
NET "EN3" LOC = B2;

You can lookup the physical connection names for the MIMAS V2 board from this website: Mimas V2 Spartan 6 FPGA Development Board With DDR SDRAM.

Next, you’ll need to select your FPGA board node and then in the processes section, you can right-click on “Generate Programming File” and select “Process Properties”.  Make sure the “Create Binary file” check box is checked.  Then right-click “Generate Programming File” again and select “Rerun All”.  That will compile and generate all the files you’ll need for your board.

Now you can startup your Configuration tool.  This can be downloaded from here (Click on Downloads and download the Configuration Tool for Windows).

You’ll need to select the COM port that corresponds to the USB port that you are using for your board.  To find that, you can open the Windows “Device Manager” and look it up.  You’ll need to plug in your Mimas board for this to show up.  You’ll see an entry in the “Ports (COM & LPT)” section:

You can see the “Numato Lab Mimas…” line and it is using COM3.  So select the COM port that your computer is setup for in the Configuration Tool.

Next, click on the “Open File” button and navigate to your project folder and click on the “.bin” file.

Then Click the “Program” button and wait for the “Done” status.

Now you can use the dip switches to turn on/off the A, B and Carry in signals:

This is a view with A, B and Carry In set to a “1”.  The LEDs represent D1=Sum and D2=Carry.  As you can see, they are both lit.

 

FPGA – Hex LED Display

After finishing the beginner’s guide for the Mimas V2 Development Board, I decided to try my hand at a circuit that I previously built with the GAL16V8 chip.  I already had the PDS file for the BCD to Hexadecimal LED display, so I decided to try that.  First, I needed to figure out what I could use for inputs.  The Mimas board has an 8-position DIP switch.  I used switch 1 through 4 for the BCD input.  I also used push button switch number 1 for the lamp test input.  If you go to this website, you can find all the schematics that show inputs and outputs.  Here are the inputs:

According to the diagram above, I chose to use M18 for the lamp test and dip switches F17, F18, E16, E18 for my BCD inputs.  All switches are active low, so I needed pull-up resistors and had to reverse the input logic to the module (a zero is inputted when the switch is ON).

Next, the outputs.  There are three 7-segment displays, so I chose display 1.  To enable the display, I applied a zero to the enable transistor.  Also, I had to disable the other two displays by applying a “1”.  Here’s the schematic:

So B3 must be set to “0” and A2 and B2 must be set to a “1”.  Then segment A is A3, segment B is B4, segment C is A4, etc.  The UCF file for the program will look like this:

# User Constraint File for BCD to 7-Segment Hex Display implementation on Mimas V2

NET "A" LOC = A3;
NET "B" LOC = B4;
NET "C" LOC = A4;
NET "D" LOC = C4;
NET "E" LOC = C5;
NET "F" LOC = D6;
NET "G" LOC = C6;
NET "EN1" LOC = B3;
NET "EN2" LOC = A2;
NET "EN3" LOC = B2;

# Switches.
# Internal pull-ups need to be enabled since 
# there is no pull-up resistor available on board
NET "D0" PULLUP;
NET "D1" PULLUP;
NET "D2" PULLUP;
NET "D3" PULLUP;
NET "LT" PULLUP;

NET "D0" LOC = F17;
NET "D1" LOC = F18;
NET "D2" LOC = E16;
NET "D3" LOC = E18;
NET "LT" LOC = M18;

Now, it’s time to create the logic.  I discovered the AND, OR, NOR, etc. circuits from this tutorial: Verilog Tutorial.  So I created OR/AND combinations for each segment like this:

and (a1, D0, D2);
and (a2, D0, !D3);
and (a3, !D1, !D2);
and (a4, !D1, D2, D3);
and (a5, !D0, !D2, D3);
and (a6, D1, D2, !D3);
nor (A, a1, a2, a3, a4, a5, a6, !LT);

This came from the following formula used in my GAL16V8 circuit:

/A = /RBO*/D0*/D2 + /RBO*/D0*D3 + /RBO*D1*D2 + /RBO*D1*/D2*/D3 + /RBO*D0*D2*/D3 + /RBO*/D1*/D2*D3 + LT

I did not implement the RBO (Ripple Blanking Output).  So, I removed all the /RBO terms.  Then I flipped all the “NOT” to be positive and all the positive to be “NOT”.  Instead of !D0 AND !D2, the first term is D0 AND D2.  Last, I ORd the lamp test (LT) with the results.  The LT button is also inverted because pressing the button produces a zero.  So you’ll notice that there is a !LT in each OR term. Since the segments are active low, I had to change all of my OR’s to NOR (the display looked rather interesting with the segments inverted).

The last part of the logic was forcing which display was on:

assign EN1 = 0; // enable digit 1
assign EN2 = 1; // disable digit 2
assign EN3 = 1; // disable digit 3

I wasn’t sure how large each Spartan 6 logic block was, so I just typed this in and expected the program to give me an error if I exceeded the number of AND/OR gates available.  Apparently, I didn’t reach that limit.  The program console shows that my program used 4 LUTs out of 5,720:

Slice Logic Utilization:
  Number of Slice Registers:                     0 out of  11,440    0%
  Number of Slice LUTs:                          4 out of   5,720    1%
    Number used as logic:                        4 out of   5,720    1%
      Number using O6 output only:               1
      Number using O5 output only:               0
      Number using O5 and O6:                    3
      Number used as ROM:                        0
    Number used as Memory:                       0 out of   1,440    0%

Apparently, the LUT (Look Up Table) is used to represent combinatorial circuits.  There is a description of the LUT in this document: Spartan-6 FPGA Configurable Logic Block User Guide

The function generators in Spartan-6 FPGAs are implemented as six-input look-up tables (LUTs). There are six independent inputs (A inputs – A1 to A6) and two independent outputs (O5 and O6) for each of the four function generators in a slice (A, B, C, and D). The function generators can implement any arbitrarily defined six-input Boolean function.
Basically, the LUT is a logic table representation of my discrete boolean logic.  Technically, I could have provided a lookup table definition, similar to mapping out a circuit in Read Only Memory.
The Code
Here’s the full listing of the UCF file:
# User Constraint File for BCD to 7-Segment Hex Display implementation on Mimas V2

NET "A" LOC = A3;
NET "B" LOC = B4;
NET "C" LOC = A4;
NET "D" LOC = C4;
NET "E" LOC = C5;
NET "F" LOC = D6;
NET "G" LOC = C6;
NET "EN1" LOC = B3;
NET "EN2" LOC = A2;
NET "EN3" LOC = B2;

# Switches.
# Internal pull-ups need to be enabled since 
# there is no pull-up resistor available on board
NET "D0" PULLUP;
NET "D1" PULLUP;
NET "D2" PULLUP;
NET "D3" PULLUP;
NET "LT" PULLUP;

NET "D0" LOC = F17;
NET "D1" LOC = F18;
NET "D2" LOC = E16;
NET "D3" LOC = E18;
NET "LT" LOC = M18;
And the V file:
module HexLED(D0,D1,D2,D3,LT, A, B, C, D, E, F, G, EN1, EN2, EN3);
    input wire D0;
    input wire D1;
    input wire D2;
    input wire D3;
    input wire LT;
    
    output wire A;
    output wire B;
    output wire C;
    output wire D;
    output wire E;
    output wire F;
    output wire G;
    output wire EN1;
    output wire EN2;
    output wire EN3;
    
    // /D0*/D2 + /D0*D3 + D1*D2 + D1*/D2*/D3 + D0*D2*/D3 + /D1*/D2*D3
    and (a1, D0, D2);
    and (a2, D0, !D3);
    and (a3, !D1, !D2);
    and (a4, !D1, D2, D3);
    and (a5, !D0, !D2, D3);
    and (a6, D1, D2, !D3);
    nor (A, a1, a2, a3, a4, a5, a6, !LT);
    
    // /D2*/D3 + /D0*/D2 + /D0*/D1*/D3 + D0*D1*/D3 + D0*/D1*D3
    and (b1, D2, D3);
    and (b2, D0, D2);
    and (b3, D0, D1, D3);
    and (b4, !D0, !D1, D3);
    and (b5, !D0, D1, !D3);
    nor (B, b1, b2, b3, b4, b5, !LT);
    
    // D0*/D1 + D0*/D2 + /D1*/D2 + D2*/D3 + /D2*D3
    and (c1, !D0, D1);
    and (c2, !D0, D2);
    and (c3, D1, D2);
    and (c4, !D2, D3);
    and (c5, D2, !D3);
    nor (C, c1, c2, c3, c4, c5, !LT);
    
    // /D0*/D1*D3 + /D0*/D2*/D3 + D0*D1*/D2 + /D0*D1*D2 + D0*/D1*D2
    and (d1, D0, D1, !D3);
    and (d2, D0, D2, D3);
    and (d3, !D0, !D1, D2);
    and (d4, D0, !D1, !D2);
    and (d5, !D0, D1, !D2);
    nor (D, d1, d2, d3, d4, d5, !LT);
    
    // /D0*/D2 + D2*D3 + /D0*D1 + D1*D3
    and (e1, D0, D2);
    and (e2, !D2, !D3);
    and (e3, D0, !D1);
    and (e4, !D1, !D3);
    nor (E, e1, e2, e3, e4, !LT);
    
    // /D0*/D1 + /D2*D3 + D1*D3 + /D0*D2 + /D1*D2*/D3
    and (f1, D0, D1);
    and (f2, D2, !D3);
    and (f3, !D1, !D3);
    and (f4, D0, !D2);
    and (f5, D1, !D2, D3);
    nor (F, f1, f2, f3, f4, f5, !LT);
    
    // D1*/D2 + D0*D3 + /D2*D3 + /D0*D1 + /D1*D2*/D3
    and (g1, !D1, D2);
    and (g2, !D0, !D3);
    and (g3, D2, !D3);
    and (g4, D0, !D1);
    and (g5, D1, !D2, D3);
    nor (G, g1, g2, g3, g4, g5, !LT);
    
    assign EN1 = 0; // enable digit 1
    assign EN2 = 1; // disable digit 2
    assign EN3 = 1; // disable digit 3
    
endmodule
 

The FPGA

I recently purchased an FPGA development board.  Specifically, the Mimas V2 Spartan 6 board.  There’s a really good introduction to this board which you can access by clicking here.  The board looks like this:

You can connect a micro-USB to USB cable to this board and program it from your PC.  Plus, the power from the USB can power the board for small circuits (there’s a power adapter that did not come with the board that you can use if the power requirements become too high).  I spent an evening going through the basic “hello world” circuit in the beginners guide and I was able to create a circuit that lit one of the small LEDs when pushing a button (I mentioned that this was the “hello world” circuit right?).  What motivated me to buy this board?

Programmable Logic – A Short History

Way back in the late 80’s (or 1978 according to Wiki) the PAL was invented.  This is a Programmable Array Logic device that is similar to the GALs that I used in my previous posts.  The basic chip came with an array of fuses that connected inputs to AND gates and you can blow fuses to “program” which input pins activated which AND gates.  Later, Generic Array Logic devices replaced these devices by substituting fuses with erasable links (electrically erasable floating gates).  These devices can be reprogrammed hundreds of times.  PALs and GALs can be used to replace several TTL logic chips for each programmable chip.

As chip sizes shrunk and more transistors could be fit on a chip new devices were invented.  CPLDs or Complex Programmable Logic Devices were nothing more than a dozen or more PALs on a chip with data buses that can be programmed to connect your sub-circuits (or modules).  The PAL-like structures on CPLDs are referred to as Macro Cells or Generic Logic Blocks.  Here’s an example of a logic block:

These blocks are wired together from a Global Routing Pool.  For the CPLD I used here, there are 16 GLBs connected with one large routing pool.

Along the same lines as the CPLD is the FPGA or Field Programmable Gate Array.  These devices are more complex than the CPLD and they are designed to be field programmable, usually incorporating flash memory.  According to Wiki, the earliest FPGAs were produced in the late 1970s.  FPGAs can contain logic blocks, memory blocks, shift registers, multiplexers and other circuits.  An entire system can be created on a single chip.  The Spartan 6 model XC6SLX9 model, used in the Mimas board I mentioned earlier, has 9,152 logic blocks and 576K of memory.  One of the largest Spartan FPGAs available today has 147,443 logic blocks and 4Meg of memory.

Using Verilog HDL

The circuitry inside an FPGA is too complex to be designed using fuse maps and schematics.  To make the job of creating a complex circuit easier, the Spartan FPGA is programmed using the Verilog Hardware Description Language (HDL).  The Verilog HDL language has “C”-like syntax and the Xilinx design tools editor is similar to Visual Studio.  This website has a pretty good tutorial on Verilog’s HDL language: ASIC World: Verilog.  I would highly recommend following the Numato Lab beginners guide to get used to the tools and the FPGA board.

The Mimas V2 Spartan-6 Board and Chip

When working on a circuit for the Mimas board this site is useful for looking up inputs and outputs: Mimas V2 Spartan 6 FPGA Development Board with DDR SDRAM.  All of the Spartan-6 chip specifications are located at the Xilinx site here: Xilinx Spartan-6 Documentation.  As I mentioned earlier the XC6SLX9 chip is used on the Mimas board.  The board schematics can be found here: Mimas V2 Schematics.

If you dig through the specifications for the Spartan FPGA, you’ll discover the CLB (Configurable Logic Block) organization which starts with this diagram:

As mentioned earlier, there are over 9000 of these blocks, of which, 4 are shown in the diagram above.  Each block contains a slice.  Each slice can be of three different circuit types: SLICEX, SLICEL and SLICEM.  Each with progressively more circuitry.  This table lists the features:

Here’s the diagram for the SLICEM:

You can refer to the documentation here to see the diagrams for the SLICEX and SLICEL.  In the SLICEM above, the 4 boxes on the left are the LUTs or Look Up Tables.  These can be used for combinatorial circuits on their own, or they can be programmed to connect any of the logic in the diagram into a complex subsystem.

Although the documentation lists the XC6SLX9 as having 9,152 logic cells, there are only 1,430 slices, which means that there are 715 CLBs.  The remaining logic cells must be circuitry other than the CLBs.  Further into the documentation is the diagram that shows how all the CLBs are connected together into an array:

Obviously, you would program modules that would be represented by a CLB and each module is interconnected together according to your defined inputs and outputs.  This simplifies the ability to design a large circuit by defining smaller sub-circuits, one module at a time.

So far, I’m only scratching the surface of what this device can do.  All I can think of is that this one chip can represent circuits beyond all the TTL chips I have stored in my box of parts (and I have quite the large collection of chips).   The price for the Mimas board is only $50 (I purchased it from here).  The Xilinx software used in the beginners guide is free, though you’ll have to fill out some information to download it (go here).

I’ll be following up with more posts on this subject as I learn what this board can do.