FPGARelated.com
Blogs

Learning VHDL - Basics

Enrico GaranteJune 15, 20135 comments

Since FPGA are becoming more accessible to the hobbyist, learning how to use them can be really useful for certain applications, like DSP and video generation; moreover, engineers that are able to code in VHDL/Verilog are always requested on the job market.

In this tutorial I will cover the basics of Xilinx ISE and VHDL. I willl base my code on the Basys2 board from Digilent: it is really cheap (especially for students) and has a lot of features on board, as you can see from the picture below. 

 

VHDL is the acronym for VHSIC Hardware Description Language (where VHSIC stands for Very High Speed Integrated Circuits). It becomes an IEEE standard in 1987 and it is the most used language (along with Verilog) to describe digital electronic systems.

VHDL seems just like any other computer language, as it uses many common construct like if, then, else. But the main difference is that it is a dataflow language: this means that it describes how several blocks of code are connected and executed at the same time. Each block of code describes a digital subsystem, with inputs and outputs. 

VHDL programming consists of two phases:

  1. ENTITY description: we state how the block is seen from outside (ports, buses, configurations...)
  2. ARCHITECTURE description: we describe how the block works internally.

Enough theory already, let's see some code...

We start referencing the main VHDL library and using the STD_LOGIC_1164.ALL package, that contains several datatypes, logic operations and functions. This should probably be included in every entity you create.

Note that every instruction is terminated with the semicolon. To create a comment just use the -- (double minus characters). 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- This is a comment.

Then we define our "black box" with the "entity" statement followed by its name and the keyword "is".

The next statement "Port" describes how many "wires" are exposed to the outside; the list is composed this way:

name     :     direction       type;

The last element of the list isn't terminated with the semicolon, but we need to terminate the Port statement.

The STD_LOGIC type is used to represent a digital value. It can assume several values like 0, 1, X (undefined), Z (high impedance) and many others.

Finally we end the definition of our entity with the "end" keyword. 

entity AndPort is
    Port ( a : in  STD_LOGIC;
           b : in  STD_LOGIC;
           y : out  STD_LOGIC);
end AndPort;

Now we describe how our component works using the "architecture" statement, followed by its name and specifying to which entity it refers with the keyword "of".

The keyword begin and end will border our architecture statement. 

architecture Behavioral of AndPort is
 
begin
 

The "process" statement is what actually describes the behavior of our component: it resembles functions from software programming languages.

We declare it this way:

name :  process     (sensitivity list)

and is delimited by the usual begin and end keywords.

The sensitivity list is a list of signals that are constantly polled: every change in one of it causes the process to execute.

Inside our process there are our instructions: we assign to the output signal y the result of the logic AND operation between a and b. This is achieved with the

func:process(a,b)
begin
   
          y<=(a and b);
end process;
 
end Behavioral;

And that's it! Here's the complete code for reference.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
entity AndPort is
    Port ( a : in  STD_LOGIC;
           b : in  STD_LOGIC;
           y : out  STD_LOGIC);
end AndPort;
 
architecture Behavioral of AndPort is
 
begin
 
func:process(a,b)
begin
              
    y<=(a and b);
end process;
 
end Behavioral;

In the video below I show how to create a new project in ISE Webpack and simulate it with ISim.

Watch it in HD and fullscreen:  http://www.youtube.com/watch?v=rMKXHDL982U



[ - ]
Comment by VitpepparJune 17, 2013
Very nice! However I think, but correct me if I'm wrong, for a comment you use two minus signs --
[ - ]
Comment by cfeltonJune 18, 2013
That is correct, the "--" is used for a comment.

In the VHDL 2008 block comments were added
"/* */".
[ - ]
Comment by egaranteJuly 2, 2013
Hi Vitpeppar, I'm sorry for the mistake, thanks for reporting it!
[ - ]
Comment by pini_krAugust 9, 2013
I would like to recommend self study VHDL projects, which can help.
IP TTL filter which is based on small examples showing how to work with list in VHDL to simplify packet operation, random number generation from VHDL, using perl script to automate state machine encoding etc ...
Please visit bknpk and look for this IP TTL filter as well as other self study projects..

[ - ]
Comment by sanghamitra6August 4, 2016
how to find one's complement of the elements of an array using vhdl

To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.

Please login (on the right) if you already have an account on this platform.

Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: