Translate

Friday, November 4, 2011

Basic VHDL elements

    Even though VHDL isn't a programming language, has some similar elements in common with the latter. Those include lexical and data type elements.

    Lexical elements
    1)  Identifiers represent names given by you to ports, signals, variables and other objects of VHDL. There are some rules for writing identifiers:
              - They contain only letters, decimal digits and underscores
              - An identifier must begin with a letter
              - The last character must not be an underscore
              - Identifiers can not contain 2 consecutive underscores
    Examples of identifiers: enable, num1, write_e
    Another important note is that VHDL is case insensitive. In translation you can write an identifier either with lower case characters, either with upper case characters. Combinations of upper and lower case is the same as well.
    Example: ENABLE, enable, EnablE are the same.

    2)  Reserved words are special language reserved words like: port, end, begin, entity, and, or, not, architecture etc. You can not use these words as identifiers.

    3)  Comments can be used to document your work. They do not influence the functionality of the program but an indispensable asset to any programmer because by documenting pieces of code you can read it very easily after a long time.
         Every comment starts with 2 dashes (--) and is line specific
    Example:  --this is a signal assignment
                    a<='0';


    Objects

    1)  Signals are the most common object used in a VHDL program. They can be seen as a wire or connection between two ports. Signals are declared after the architecture name and before the begin statement.


              architecture arch_a of arch is
                  signal a,b :  std_logic;
              begin
    
    In the architecture body you assign values to signals with <= like so:


               a<='1';
               b<=a;


    The entity ports are considered signals to. 
    

    2) Constants are objects are given a value and it does not change. Usually they are written with capital letters and are declared after the architecture with signals. Example of constant declaration:

     
              constant BITS : integer := 8;


    As you can see the constant is named BITS, is of type integer (we'll get to that later) and has the value 8.


    3) Variables are used only in sequential code (process). Their role is to describe complex algorithms in circuits. A variable is local to the process in witch it is declared.
    Example:

              process()
                  variable count : integer;
              begin

     To assign a value to a variable we use := like:
           
              count := 0;


    

    Basic data types
    In order to use objects in a program they need to have a data type.


    The most used data types in a VHDL program are std_logic and std_logic_vector. They are the most used because the values held by them are 0 or 1 witch represent binary numbers (the basis of digital electronics). Another value they can be given is Z witch stands for high impedance (it is used when designing circuits that communicate to a common bus).
    The difference between the 2 types is that std_logic holds a single value of 0 or 1 or Z and std_logic_vector is a unidimensional array of std_logics so it holds as many values as we want.
    Example declarations:
           
              signal enable : std_logic;
              signal num1 : std_logic_vector(7 downto 0);


    From the above we can determine that num1 is an array of 8 std_logic values (7 downto 0 means that it has 8 elements numbered from 7 to 0). Vectors can be used entirely by referencing the name (ex: num1), bit by bit using an index (ex num1(0) means the left most bit or least significant bit) or by chunks of several bits (ex: num1(2 downto 0) references the left most 3 bits)

    Examples of assigning values:
 
              enable <= '0';
              enable <= '1';
              num1 <= "10110001";
              num1 <= "00000000";
              num1 <= (others => '0');
              

    The examples are straight forward and ,I hope, don't need explaining.

    Basic operators used on these types are: not, and, nand, or, nor, xor, xnor.
    Also useful is the concatenation operator: &. Example of using &:

              --the result of the following expression is "11110000"
              num1 <= "1111"&"0000";


    If we want to perform more complex math functions on numbers three data types can be used: integer, signde and unsigned. The last 2 can be used only after including the numeric.std package.
    Integers are 32 bit numbers and basically any math operator can be performed on them (+,- ,*, / ,mod,rem) but it's hard to translate an integer into digital circuits. That's where the unsigned and signed types step in. They are formed with std_logic elements and can be used with all the operators that integers can be used with.
    For the most designs you will be using mostly unsigned because signed elements have the most significant bit dedicated to the sign of the number (+/-)

    All of these concepts will be clear when we will do more example designs. For now it's best to try to understand most of them.
    More advanced operators and data types will be presented in later tutorials.

No comments:

Post a Comment