APS-X84 VHDL/FPGA SYNTHESIS TUTORIAL

VHDL INTRODUCTION

VHDL stands for VHSIC Hardware Description Language. The VHSIC acronym stands for Very High Speed Integrated Circuits. It is a language used to describe the implementation of hardware. Entire books exist which do a great job of describing the VHDL language in detail. Our goal is not to try and do this here, but rather to give essential elements of the language which will enable the user to quickly synthesize designs. This is No Frills Basic VHDL Synthesis. That being said lets get started.

The Skeleton: A VHDL boilerplate

The basic building blocks of a synthesizable VHDL design can be broken up into the following :

Here's an example of a VHDL design for an AND gate.
library IEEE; 
use IEEE.std_logic_1164.all; 

library METAMOR; 
use METAMOR.attributes.all; 

library SYNOPSYS; 
use SYNOPSYS.std_logic_arith.all; 
use SYNOPSYS.std_logic_unsigned.all; 

-- 
-- Begin Entity (This is a comment) 
-- 
ENTITY ANDGATE IS 
               PORT 
                 ( 
                         Ain: in STD_LOGIC; 
                         Bin: in STD_LOGIC ; 
                         COut: out STD_LOGIC 
                 ); 
                END ANDGATE; 

--  
-- Begin Architecture (This is a comment) 
-- 
ARCHITECTURE behave OF ANDGATE IS 

BEGIN 

             COut <= Ain AND Bin; 

END behave; 

As can be seen here there is probably more of what I term DECLARATIONS here than actual VHDL code (after all it is just an and gate). The declaration portions is shown below:
library IEEE; 
use IEEE.std_logic_1164.all; 

library METAMOR; 
use METAMOR.attributes.all; 

library SYNOPSYS; 
use SYNOPSYS.std_logic_arith.all; 
use SYNOPSYS.std_logic_unsigned.all; 

These are DECLARATION statements , much like C include files, telling the compiler which external files/libraries to use. First the library is declared, and then portions or all of it can be used.  Let's go over the few shown here

IEEE.std_logic_1164 - This is the basic IEEE VHDL library which declares different a type of logic which we will use continually. The std_logic type is basically a bit (1 or 0) with some additional features like high impedance (Z) and don't cares (X). Operations and conversion routines are also defined in this library. The .all statement tells the compiler to use all the elements/routine/libraries contained in the IEEE.std_logic  library. This file is usually in text format and can be printed out and viewed. It is  VHDL code. In the FOUNDATION series
the file is located in :

active\vhdl\vhdl_lib\ieee.vhd

The same can be said for metamor.vhd and synopsys.vhd. It might be a good idea to stop and just take a look at these files.

The ENTITY is the formal declaration of the top level of the module you are designing:
ENTITY ANDGATE IS 
               PORT 
                 ( 
                         Ain:         in         STD_LOGIC; 
                         Bin:         in         STD_LOGIC ; 
                         COut:     out        STD_LOGIC 
                 ); 
 END ANDGATE; 
Notice that our name ANDGATE is surrounded by the keywords ENTITY and  IS. Then the keyword PORT and then inside the parenthesis our top level elements (perhaps pins) are described. Ain is an input thus the keyword IN is used. The input is of the type std_logic (basically just a bit). VHDL IS NOT context sensitive and so IN is the same as In or in or iN. Also notice her that the last declaration COut is not terminated with a semicolon (I don't know why they did this they just did, and you have to remember it, or your compiler will constantly remind you.)

Now that we have the Io elements defined, we will now describe the behavior in the ARCHITECTURE section:
ARCHITECTURE behave OF ANDGATE IS 

BEGIN 

             COut <= Ain AND Bin; 

END behave; 

Basically the Architecture starts off with an Architecture statement and we named this architecture behave and it is the behave architecture of our ANDGATE entity.  Like PASCAL we use BEGIN and END statements to contain our architecture code. Different architectures can exist for our ANDGATE design but we will not use or delve into that aspect of VHDL here. For our architecture we have simply stated that COut is equal to Ain AND Bin. The AND function is described in one of the libraries described above. If you wish to see see the VHDL which implements it feel free to do so. For now you only need understand that this will logically AND the two bits together and produce an output bit (Cout) which is the result of Ain logically ANDed with Bin. The <= operator is the assignment operator for SIGNALS and entity elements (perhaps pins). The = operator is used in IF statements for comparisons. This is much like the == and = statements in C.

For our initial examples we will keep our designs to one ENTITY. As will be seen later in our more advanced examples, we can compile our entities as MACROs or CHIPs. The module compiled as CHIP will be the upper most entity. Other entities can be compiled as MACROs and included modularly with other MACROs and interconnected in the CHIP module.

We should mention here that text on a line followed by two dashes are considered comments and are ignored by the VHDL compiler.
-- 
-- Begin Entity (This is a comment) 
--
So there you have it. Your first VHDL program and we have covered a couple of key topics to boot. The same basic structure will be used throughout this text, in the examples we put forth. As can be seen here we haven't really assigned pin numbers from our device to the design, but apart from that we could synthesize, route and download this design right into an FPGA. So let's assign some pins. We will need to add some additional statements called ATTRIBUTES which will be used to define the pins we want to use. Taking a look at our X84 FPGA board schematics (included with the X84 board),  we see that we have an on board utility LED which will work nicely as an output indicator. It's tied to pin 35 of the FPGA chip. The following statement placed inside the ENTITY statement (which makes sense since the ENTITY declares the TOP LEVEL items of our module).
ATTRIBUTE pinnum of COut: signal is "P35";
We could further add the attributes for the remaining pins to get a new ENTITY that looks like:
library IEEE; 
use IEEE.std_logic_1164.all; 

library METAMOR; 
use METAMOR.attributes.all; 

library SYNOPSYS; 
use SYNOPSYS.std_logic_arith.all; 
use SYNOPSYS.std_logic_unsigned.all; 
-- 
-- Begin Entity (This is a comment) 
-- 
ENTITY ANDGATE IS 
               PORT 
                 ( 
                         Ain:         in         STD_LOGIC; 
                         Bin:         in         STD_LOGIC ; 
                         COut:     out        STD_LOGIC 
                 ); 

            ATTRIBUTE pinnum of COut: signal is "P35"; 
            ATTRIBUTE pinnum of Ain: signal is "P3"; 
            ATTRIBUTE pinnum of Bin: signal is "P4"; 

END ANDGATE; 
--  
-- Begin Architecture (This is a comment) 
-- 
ARCHITECTURE behave OF ANDGATE IS 

BEGIN 

             COut <= Ain AND Bin; 

END behave; 

Notice that the attributes were placed outside of the PORT declarations but inside of the ENTITY BEGIN and END.

We choose the two input pins so that they were attached to two of the twenty four 8255 pins which provide programmable IO to the FPGA on the APS-X84 board.  After we synthesize and route the AND GATE design we will write some short C code which will enable us to download the FPGA image file (produced from our synthesized and routed VHDL design) and then actually set the two inputs to different values and watch the X84 utility LED change values.