You are on page 1of 89

VHDL Data Types

Predefined types bit '0' or '1' boolean FALSE or TRUE integer an integer in the range (231 1) to +(231 1) (some implementations support a wider range) real floating-point number in the range 1.0E38 to +1.0E38 character any legal VHDL character including upper- and lowercase letters, digits, and special characters (each printable character must be enclosed in single quotes; e.g., 'd','7','+') time an integer with units fs, ps, ns, us, ms, sec, min, or hr

User-defined Data Types


Enumeration type type state_type is (S0, S1, S2, S3, S4, S5); signal state : state_type := S1;

define a signal called state that can have any one of the values S0, S1, S2, S3, S4, or S5, and that is initialized to S1.

Copyright Dr. Lizy John, The University of Texas at Austin

Data Type Conversion


VHDL is a strongly typed language Signal and variable data types cannot be mixed No automatic type conversion is performed If signals and variables of multiple types need to be used, explicit type conversion should be performed

Overloaded operators can be defined in libraries

Copyright Dr. Lizy John, The University of Texas at Austin

Predefined VHDL Operators


Grouped into seven classes: 1. Binary logical operators: and or nand nor xor xnor 2. Relational operators: = /= < <= > >= 3. Shift operators: sll srl sla sra rol ror 4. Adding operators: + & (concatenation) 5. Unary sign operators: + 6. Multiplying operators: * / mod rem 7. Miscellaneous operators: not abs **
When parentheses are not used, operators in class 7 have highest precedence
Copyright Dr. Lizy John, The University of Texas at Austin

Operator Precedence: 1. and or nand nor xor xnor

2. = /= < <= > >=

Evaluate
(A & not B or C ror 2 and D) = "110010"

3. sll srl sla sra rol ror 4. + & (concatenation) 5. sign operators: +

6. * / mod rem
7. not abs **

This is an equality test; not an assignment statement. The operators are applied in the order: not, &, ror, or, and, =

If A = "110", B = "111", C = "011000", and D = "111011", not B = "000" (bit-by-bit complement) A & not B = "110000" (concatenation) C ror 2 = "000110" (rotate right 2 places) (A & not B) or (C ror 2) = "110110 (bit-by-bit or) (A & not B or C ror 2) and D = "110010" (bit-by-bit and) [(A & not B or C ror 2 and D) = "110010"] = TRUE (the parentheses force the equality test to be done last and the result is TRUE)

Copyright Dr. Lizy John, The University of Texas at Austin

Operators
Class 1 operators and the not operator can be applied to bits, booleans, bit-vectors and boolean vectors Result of relational (class 2) operator is a boolean (TRUE or FALSE) = and /= can be applied to almost any type Other relational operators can be applied to numeric, enumerated and some array types

If A=5, B=4, and C=3, (A >= B) and (B <= C) evaluates to FALSE.

Copyright Dr. Lizy John, The University of Texas at Austin

Shift operators
The shift operators can be applied to any bit_vector or boolean_vector. If A is a bit_vector equal to "10010101": A sll 2 A srl 3 A sla 3 A sra 2 A rol 3 A ror 5 is is is is is is "01010100" "00010010" "10101111" "11100101" "10101100" "10101100" (shift left logical, filled with '0') (shift right logical, filled with '0') (shift left arithmetic, filled with right bit) (shift right arithmetic, filled with left bit) (rotate left) (rotate right)

Copyright Dr. Lizy John, The University of Texas at Austin

Arithmetic operators
The + and operators can be applied to integer or real numeric operands. The + and operators are not defined for bits or bit-vectors. That is why we had to make a full adder by specifically creating carry and sum bits for each bit. However, several standard libraries do provide functions for + and that can work on bit-vectors

If we use such a library, we can perform addition using the statement C <= A + B.

Copyright Dr. Lizy John, The University of Texas at Austin

Arithmetic operators
The & operator can be used to concatenate two vectors "010" & '1' is "0101" "ABC" & "DEF" is "ABCDEF". The * and / operators perform multiplication and division on integer or floating-point operands. The rem and mod operators calculate the remainder and modulus for integer operands.

The ** operator raises an integer or floating-point number to an integer power, and abs finds the absolute value of a numeric operand.

Copyright Dr. Lizy John, The University of Texas at Austin

Overloaded operators
In standard VHDL, some operations are valid only for certain data types. For other data types, use overloading to create an overloaded operator. Concept of "function overloading" as in many general-purpose languages. Two or more functions may have the same name, so long as the parameter types are sufficiently different enough to distinguish which function is actually intended. Overloaded functions can also be created to handle operations involving heterogeneous data types.
Copyright Dr. Lizy John, The University of Texas at Austin

VHDL Libraries
IEEE std_logic library IEEE; use IEEE.STD_LOGIC_1164.ALL;
IEEE numeric bit
library IEEE; use IEEE.numeric_bit.ALL;
These are IEEE standards

Despite its name, this is not an IEEE standard

IEEE numeric std


library IEEE; use IEEE.numeric_std.ALL;

BITLIB is a custom library used in the book


Copyright Dr. Lizy John, The University of Texas at Austin

Numeric bit library


IEEE standard To get bit vector use type unsigned. (Unsigned means an unsigned vector) Conversion functions: TO_INTEGER(A) converts an unsigned vector A to an integer TO_UNSIGNED(B,N) converts an integer to an unsigned vector of length N
Copyright Dr. Lizy John, The University of Texas at Austin

Numeric bit library


Provides overloaded operator to add integer to unsigned, but not to add a bit to unsigned.
If A and B are unsigned, A+B+1 is allowed Sum <= A + B + carry; is not allowed when carry is of type bit.

The carry must be converted to an integer before it can be added to the unsigned vector A + B.

Copyright Dr. Lizy John, The University of Texas at Austin

Simple Synthesis Example


library IEEE; use IEEE.numeric_bit.ALL; entity Q1 is port(A, B: in bit; C: out bit); end Q1; architecture Q1 of Q1 is begin process (A) begin C <= A or B after 5 ns; end process; end architecture;
Copyright Dr. Lizy John, The University of Texas at Austin

What will be the synthesizer output?

Synthesizer Output

Copyright Dr. Lizy John, The University of Texas at Austin

Simulation versus synthesis


library IEEE; use IEEE.numeric_bit.ALL; entity Q1 is port(A, B: in bit; C: out bit); end Q1; architecture Q1 of Q1 is begin process (A) begin C <= A or B after 5 ns; end process; end architecture;
Copyright Dr. Lizy John, The University of Texas at Austin

If you simulate this, is it equivalent to an OR gate? What if B changes? Note: B is not in the sensitivity list

Synthesizer Output

Synthesizer still produces OR gate Discrepancy with simulation May be blessing here Moral: Do not ignore synthesizer warnings make sure they are harmless

Copyright Dr. Lizy John, The University of Texas at Austin

Synthesis Example
library IEEE; use IEEE.numeric_std.ALL; entity Q3 is port(A,B,F, CLK: in bit; D: out bit); end Q3;

architecture Q3 of Q3 is signal C: bit; begin


process(Clk) begin if (Clk=1 and Clkevent) then C <= A and B; -- statement 1 D <= C or F; -- statement 2 end if; end process; end Q3;
Copyright Dr. Lizy John, The University of Texas at Austin

Synthesis Example
library IEEE; use IEEE.numeric_bit.ALL; entity Q3 is port(A,B,F, CLK: in bit; D: out bit); end Q3;

architecture Q3 of Q3 is signal C: bit; begin


process(Clk) begin if (Clk=1 and Clkevent) then C <= A and B; -- statement 1 D <= C or F; -- statement 2 end if; end process; end Q3;
Copyright Dr. Lizy John, The University of Texas at Austin

What is inside the block? 2 Gates?

Hardware corresponding to VHDL code

Latches in addition to gates

When synthesizer generates latches, Check whether intentional latches or undesirable ones
Copyright Dr. Lizy John, The University of Texas at Austin

Example VHDL code that will not synthesize


library IEEE; use IEEE.numeric_std.ALL; entity nosyn is port(A,B, CLK: in bit; D: out bit); end no-syn; architecture no-syn of no-syn is begin process(Clk) variable C: bit; begin if (Clk='1' and Clk'event) then C := A and B; end if; end process; end no-syn;
Copyright Dr. Lizy John, The University of Texas at Austin

Example VHDL code that will not synthesize


library IEEE; use IEEE.numeric_std.ALL; entity nosyn is port(A,B, CLK: in bit; D: out bit); end no-syn; architecture no-syn of no-syn is begin process(Clk) variable C: bit; begin if (Clk='1' and Clk'event) then C := A and B; end if; end process; end no-syn;
Copyright Dr. Lizy John, The University of Texas at Austin

This code will not synthesize because output D is never assigned

Results in warnings: Input <CLK> is never used. Input <A> is never used. Input <B> is never used. Output <D> is never assigned

2-to-1 Multiplexer

-- conditional signal assignment statement F <= I0 when A = '0' else I1;

Copyright Dr. Lizy John, The University of Texas at Austin

Conditional signal assignment


General form
signal_name <= expression1 when condition1 else expression2 when condition2 [else expressionN];

[ ] means optional

Copyright Dr. Lizy John, The University of Texas at Austin

Cascaded 2-to-1 MUXes

F <= A when E = '1' else B when D = '1' else C;

Copyright Dr. Lizy John, The University of Texas at Austin

4-to-1 Multiplexer using concurrent stmt F = A'B'I0 + A'B I1 + A B'I2 + A B I3

F <= (not A and not B and I0) or (not A and B and I1) or (A and not B and I2) or (A and B and I3);

Copyright Dr. Lizy John, The University of Texas at Austin

4-to-1 Multiplexer using select F = A'B'I0 + A'B I1 + A B'I2 + A B I3


sel <= A&B; -- selected signal assignment -- statement with sel select F <= I0 when "00", I1 when "01", I2 when "10", I3 when "11";

Copyright Dr. Lizy John, The University of Texas at Austin

4-to-1 Multiplexer using processes


Inside process, sequential stmt needs to be used Eg: Case
case Sel is when 0 => F <= I0; when 1 => F <= I1; when 2 => F <= I2; when 3 => F <= I3; end case;

Copyright Dr. Lizy John, The University of Texas at Austin

Cyclic Shift Register

process(CLK) begin if CLK'event and CLK = '1' then Q1 <= Q3 after 5 ns; Q2 <= Q1 after 5 ns; Q3 <= Q2 after 5 ns; end if; end process;

Copyright Dr. Lizy John, The University of Texas at Austin

Register with Synchronous Clear and Load

process (CLK) begin if CLK'event and CLK = '1' then if CLR = '1' then Q <= "0000"; elsif Ld = '1' then Q <= D; end if; end if; end process;

Copyright Dr. Lizy John, The University of Texas at Austin

Left Shift Register with Synchronous Clear and Load


process (CLK) begin if CLK'event and CLK = '1' then if CLR ='1' then Q <= "0000"; elsif Ld ='1' then Q <= D; elsif Ls ='1' then Q <= Q(2 downto 0)& Rin; end if; end if; end process;

Copyright Dr. Lizy John, The University of Texas at Austin

VHDL Code for a Simple Synchronous Counter


signal Q: unsigned(3 downto 0); ----------process (CLK) begin if CLK' event and CLK = '1' then if ClrN = '0' then Q <= "0000"; elsif En = '1' then Q <= Q + 1; end if; end if; end process;

Copyright Dr. Lizy John, The University of Texas at Austin

74163 counter

74163 is available in TTL and CMOS. What does TTL stand for? What does CMOS stand for?

Copyright Dr. Lizy John, The University of Texas at Austin

74163 counter
Control Signals
ClrN 0 1 1 1 X 0 1 1 LdN X X 0 1 PT Q3 +

Next State
Q2 + Q1 + 0 D0 Q0 Q0 + (clear) (parallel load) (no change) (increment count)

0 0 0 D3 D2 D1 Q3 Q2 Q1 present state + 1

If T = 1, the counter generates a carry (Cout) in state 15, so Cout = Q3 Q2 Q1 Q0 T


Copyright Dr. Lizy John, The University of Texas at Austin

74163 Counter Model


1 2 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 library IEEE; use IEEE.numeric_bit.ALL; entity c74163 is port(LdN, ClrN, P, T, ClK: in bit; D: in unsigned(3 downto 0); Cout: out bit; Qout: out unsigned(3 downto 0) ); end c74163; architecture b74163 of c74163 is signal Q: unsigned(3 downto 0); -- Q is the counter register begin Qout <= Q; Cout <= Q(3) and Q(2) and Q(1) and Q(0) and T; process (Clk) begin if Clk'event and Clk = '1' then -- change state on rising edge if ClrN = '0' then Q <= "0000"; elsif LdN = '0' then Q <= D; elsif (P and T) = '1' then Q <= Q+1; end if; end if; end process; end b74163;

Copyright Dr. Lizy John, The University of Texas at Austin

Two 74163 Counters Cascaded to Form an 8bit Counter

Copyright Dr. Lizy John, The University of Texas at Austin

VHDL for 8-bit Counter


1 2 5 6 7 8 9 10 11 12 13 14 15

library IEEE; use IEEE.numeric_bit.ALL; entity eight-bit-counter is port(ClrN,LdN,P,T1,Clk: in bit; Din1, Din2: in unsigned(3 downto 0); Count: out integer range 0 to 255; Carry2: out bit); end eight-bit-counter; architecture cascaded-counter of eight-bit-counter is component c74163 port(LdN, ClrN, P, T, Clk: in bit; D: in unsigned(3 downto 0); Cout: out bit; Qout: out unsigned(3 downto 0) ); 16 end component; signal Carry1: bit; signal Qout1, Qout2: unsigned(3 downto 0); begin ct1: c74163 port map (LdN,ClrN,P,T1,Clk,Din1,Carry1, Qout1); ct2: c74163 port map (LdN,ClrN,P,Carry1,Clk,Din2,Carry2,Qout2); Count <= to_integer(Qout2 & Qout1); end tester;

17 18 19 20 21 22 23

Copyright Dr. Lizy John, The University of Texas at Austin

Synthesis of VHDL Code from Shift register

Copyright Dr. Lizy John, The University of Texas at Austin

Synthesis Tips

A VHDL synthesizer cannot synthesize delays. Clauses of the form "after time-expression" will be ignored by most synthesizers, but some synthesizers require that after clauses be removed. initial values are ignored by the synthesizer. A reset signal should be provided if the hardware must be set to a specific initial state.

Copyright Dr. Lizy John, The University of Texas at Austin

Synthesis Tips
If the range of an integer is not specified, the synthesizer will assume the maximum number of bits, usually 32. Thus signal count: integer range 0 to 7; would result in a 3-bit counter, but signal count: integer; could result in a 32-bit counter.
Copyright Dr. Lizy John, The University of Texas at Austin

Unwanted latches
VHDL signals retain their current values until they are changed. if X = '1' then B <= 1; end if; would create latches to hold the value of B when X changed to '0'. May be a mux was intended. Solution: Include an else clause in every if statement. if X = '1' then B<= 1 else B <= 0; end if; would create a MUX.

Copyright Dr. Lizy John, The University of Texas at Austin

Different Levels of abstraction of a NAND device

Copyright Dr. Lizy John, The University of Texas at Austin

A block diagram with A, B, C as inputs and F=ab + bc as output

Copyright Dr. Lizy John, The University of Texas at Austin

Two implementations of F=ab + bc

F=ab+bc simply describes the functionality, whereas the 2 structures specify how F is realized.
Copyright Dr. Lizy John, The University of Texas at Austin

Block diagram of sequential machine

BCD to Excess-3 Code Converter

Copyright Dr. Lizy John, The University of Texas at Austin

Behavioral Model for Excess-3 Code Converter


entity Code_Converter is Port ( X, CLK : in bit Z : out bit); end Fig2_13; architecture Behavioral of Code_Converter is signal State, Nextstate: integer := 0; begin process(State,X) --Combinational Network begin case State is when 0 => if X='0' then Z<='1'; Nextstate<=1; end if; if X='1' then Z<='0'; Nextstate<=2; end if; when 1 => if X='0' then Z<='1'; Nextstate<=3; end if; if X='1' then Z<='0'; Nextstate<=4; end if; when 2 => if X='0' then Z<='0'; Nextstate<=4; end if; if X='1' then Z<='1'; Nextstate<=4; end if;

Copyright Dr. Lizy John, The University of Texas at Austin

Code Converter(contd)

when 3 => if X='0' then Z<='0'; if X='1' then Z<='1'; when 4 => if X='0' then Z<='1'; if X='1' then Z<='0'; when 5 => if X='0' then Z<='0'; if X='1' then Z<='1'; when 6 => if X='0' then Z<='1'; when others => null; end case; end process; process(CLK) begin if CLK='1' and CLK'EVENT State <= Nextstate; end if; end process; end Behavioral;

Nextstate<=5; end if; Nextstate<=5; end if;


Nextstate<=5; end if; Nextstate<=6; end if; Nextstate<=0; end if; Nextstate<=0; end if; Nextstate<=0; end if; -- should not occur

-- State Register
then -- rising edge of clock

Copyright Dr. Lizy John, The University of Texas at Austin

Waveforms for Code Converter


wave CLK X State NextState Z force CLK 0 0, 1 100 -repeat 200 force X 0 0, 1 350, 0 550, 1 750, 0 950, 1 1350 run 1600

Copyright Dr. Lizy John, The University of Texas at Austin

Behavioral Model for Excess-3 Converter Using a Single Process


library IEEE; use IEEE.numeric_bit.ALL; entity SM1_2 is port(X, CLK: in bit; Z: out bit); end SM1_2; architecture Table of SM1_2 is signal State, Nextstate: integer := 0; begin process begin case State is when 0 => if X='0' then Z<='1'; Nextstate<=1; end if; if X='1' then Z<='0'; Nextstate<=2; end if; when 1 => if X='0' then Z<='1'; Nextstate<=3; end if; if X='1' then Z<='0'; Nextstate<=4; end if;

Copyright Dr. Lizy John, The University of Texas at Austin

Behavioral Model for Excess-3 Converter Using a Single Process (Contd)


when 2 => if X='0' then Z<='0'; Nextstate<=4; end if; if X='1' then Z<='1'; Nextstate<=4; end if;
when 3 => if X='0' then Z<='0'; Nextstate<=5; end if; if X='1' then Z<='1'; Nextstate<=5; end if; when 4 => if X='0' then Z<='1'; Nextstate<=5; end if; if X='1' then Z<='0'; Nextstate<=6; end if; when 5 => if X='0' then Z<='0'; Nextstate<=0; end if; if X='1' then Z<='1'; Nextstate<=0; end if;
Copyright Dr. Lizy John, The University of Texas at Austin

Behavioral Model for Excess-3 Converter Using a Single Process (Contd)


when 6 => if X='0' then Z<='1'; Nextstate<=0; end if; when others => null; -- should not occur end case; wait on CLK, X; if CLK = 1 and CLKevent then State <= Nextstate; end if; end process; end table;
Copyright Dr. Lizy John, The University of Texas at Austin

Synthesized Mealy machine

Copyright Dr. Lizy John, The University of Texas at Austin

Synthesized vs Manual Design

Synthesized

7 D FFs, 15 2-input AND, 3 2-input OR gates, 1 7input OR gate One-hot 3 FFs 4 3-in NAND 3 2-in NAND Encoded

Manual

Copyright Dr. Lizy John, The University of Texas at Austin

Sequential Machine Model Using Equations


-- The following state assignment was used: -- S0-->0; S1-->4; S2-->5; S3-->7; S4-->6; S5-->3; S6-->2 entity SM1_2 is port(X,CLK: in bit; Z: out bit); end SM1_2; architecture Equations1_4 of SM1_2 is signal Q1,Q2,Q3: bit; begin process(CLK) begin if CLK='1' then -- rising edge of clock Q1<=not Q2 after 10 ns; Q2<=Q1 after 10 ns; Q3<=(Q1 and Q2 and Q3) or ((not X) and Q1 and (not Q3)) or (X and (not Q1) and (not Q2)) after 10 ns; end if; end process; Z<=((not X) and (not Q3)) or (X and Q3) after 20 ns; end Equations1_4;

Copyright Dr. Lizy John, The University of Texas at Austin

Structural Model of Sequential Machine


The following is a STRUCTURAL VHDL description of -- the excess 3 converter
library UNISIM; use UNISIM.Vcomponents.ALL; entity SM1_2 is port(X,CLK: in bit; Z: out bit); end SM1_2;

Copyright Dr. Lizy John, The University of Texas at Austin

Structural Model of Sequential Machine


architecture Structure of SM1_2 is signal A1,A2,A3,A5,A6,D3: bit:='0'; signal Q1,Q2,Q3: bit:='0'; signal Q1N,Q2N,Q3N, XN: bit:='1';
begin I1: Inverter port map (X,XN); G1: Nand3 port map (Q1,Q2,Q3,A1); G2: Nand3 port map (Q1,Q3N,XN,A2); G3: Nand3 port map (X,Q1N,Q2N,A3); G4: Nand3 port map (A1,A2,A3,D3); FF1: DFF port map (Q2N,CLK,Q1,Q1N); FF2: DFF port map (Q1,CLK,Q2,Q2N); FF3: DFF port map (D3,CLK,Q3,Q3N); G5: Nand2 port map (X,Q3,A5); G6: Nand2 port map (XN,Q3N,A6); G7: Nand2 port map (A5,A6,Z); end Structure;
Copyright Dr. Lizy John, The University of Texas at Austin

Variables and Signals

A variable declaration has the form variable list_of_variable_names : type_name [ :=initial_value]; A signal declaration has the form signal list_of_signal_names : type_name [ := initial_value ]; Variables are updated using a variable assignment statement of the form variable_name := expression; Consider a signal assignment of the form signal_name <= expression [after delay]; Incorrect to say variable_name <= expression [after delay];

Copyright Dr. Lizy John, The University of Texas at Austin

Process Using Variables and Simulation Output


entity dummy is end dummy;
architecture var of dummy is signal trigger, sum: integer:=0; begin process variable var1: integer:=1; variable var2: integer:=2; variable var3: integer:=3; begin wait on trigger; var1 := var2 + var3; var2 := var1; var3 := var2; sum <= var1 + var2 + var3; end process; end var;
Copyright Dr. Lizy John, The University of Texas at Austin

ns

delta

trigger

Var1

Var2

Var3

sum

+0

+1

10

+0

10

+1

15

Process Using Signals and Simulation Output


entity dummy is end dummy; architecture sig of dummy is signal trigger, sum: integer:=0; signal sig1: integer:=1; signal sig2: integer:=2; signal sig3: integer:=3; begin process begin wait on trigger; sig1 <= sig2 + sig3; sig2 <= sig1; sig3 <= sig2; sum <= sig1 + sig2 + sig3; end process; end sig;
Copyright Dr. Lizy John, The University of Texas at Austin

Simulation Output of 2-60


ns 0 0 10 10 delta +0 +1 +0 +1 trigger 0 0 1 1 Sig1 1 1 1 5 Sig2 2 2 2 1 Sig3 3 3 3 2 sum 0 0 0 9

Process Using Variables and Simulation Output


entity dummy is end dummy;
architecture var of dummy is signal trigger, sum: integer:=0; begin process ns variable var1: integer:=1; variable var2: integer:=2; variable var3: integer:=3; begin 0 var1 := var2 + var3; var2 := var1; var3 := var2; 0 sum <= var1 + var2 + var3; wait on trigger end process; end var;

delta trigger Var1 +0 +1 0 0 1 1 1 5 10 10

Var2 Var3 sum 2 5 10 10 3 5 10 10 0 15 15 30

10 +0 10 +1

Copyright Dr. Lizy John, The University of Texas at Austin

Process Using Variables and Simulation Output


entity dummy is end dummy;
architecture var of dummy is signal trigger, sum: integer:=0; begin process (trigger) variable var1: integer:=1; variable var2: integer:=2; variable var3: integer:=3; begin var1 := var2 + var3; var2 := var1; var3 := var2; sum <= var1 + var2 + var3; end process; end var;
Copyright Dr. Lizy John, The University of Texas at Austin

ns

delt

trigge a r 0

Var1

Var2

Var3

sum

+0

+1

15

10

+0

10

10

10

15

10

+1

10

10

10

30

Process Using Signals and Simulation Output


entity dummy is end dummy;
architecture sig of dummy is signal trigger, sum: integer:=0; signal sig1: integer:=1; signal sig2: integer:=2; signal sig3: integer:=3; begin process begin sig1 <= sig2 + sig3; sig2 <= sig1; sig3 <= sig2; sum <= sig1 + sig2 + sig3; wait on trigger; end process; end sig;
ns delta trigge r 0 Sig1 Sig2 Sig3 sum

+0

+1

10

+0

10

+1

Copyright Dr. Lizy John, The University of Texas at Austin

Process Using Signals and Simulation Output


entity dummy is end dummy;
architecture sig of dummy is signal trigger, sum: integer:=0; signal sig1: integer:=1; signal sig2: integer:=2; signal sig3: integer:=3; begin process begin process(trigger); sig1 <= sig2 + sig3; sig2 <= sig1; sig3 <= sig2; sum <= sig1 + sig2 + sig3; end process; end sig;
ns delta trigger Sig1 Sig2 Sig3 sum

+0

+1

10

+0

10

+1

Copyright Dr. Lizy John, The University of Texas at Austin

Constants

A common form of constant declaration is


constant constant_name : type_name := constant_value; A constant delay1 of type time having the value of 5 ns can be defined as

constant delay1 : time := 5 ns;

Copyright Dr. Lizy John, The University of Texas at Austin

Arrays
To create array - declare an array type and declare an array object Example of declaring an array type: A one-dimensional array type named SHORT_WORD: type SHORT_WORD is array (15 downto 0) of bit; SHORTWORD is the name of the type Now, one can declare array objects of type SHORT_WORD as follows: signal DATA_WORD: SHORT_WORD; variable ALT_WORD: SHORT_WORD := "0101010101010101"; constant ONE_WORD: SHORT_WORD := (others => '1'); All bits set to 1 by (others => 1)
Copyright Dr. Lizy John, The University of Texas at Austin

Arrays
The array type and array object declarations have the general forms type array_type_name is array index_range of element_type; signal array_name: array_type_name [ := initial_values ];

Copyright Dr. Lizy John, The University of Texas at Austin

Matrices

type matrix4x3 is array (1 to 4, 1 to 3) of integer;


variable matrixA: matrix4x3 := ((1, 2, 3), (4, 5, 6), (7, 8, 9), (10,11,12)); The variable matrixA, will be initialized to 1 2 3 4 5 6 7 8 9 10 11 12 matrixA(3,2) references 8

Copyright Dr. Lizy John, The University of Texas at Austin

Unconstrained array type

When an array type is declared, the dimensions of the array may be left undefined. This is referred to as an unconstrained array type. For example, type intvec is array (natural range <>) of integer; signal intvec5: intvec(1 to 5) := (3,2,6,8,1);
Two dimensional array type matrix is array (natural range <>, natural range <>) of integer;

Copyright Dr. Lizy John, The University of Texas at Austin

Parity Code Generator using LUT

A
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1

LUT contents for a parity code generator Input (LUT Address=ABCD)

B
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1

C
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1

D
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1

P
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1

Q
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1

Output (LUT Data=PQRST)

R
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1

S
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1

T
1 0 1 1 0 1 0 0 0 1 1 0 1 0 0 1

Copyright Dr. Lizy John, The University of Texas at Austin

Parity Code Generator

Parity code generator using LUT method

library IEEE; use IEEE.numeric_bit.all; entity parity_gen is port (X: in unsigned(3 downto 0); Y: out unsigned(4 downto 0)); end parity_gen; architecture Table of parity_gen is type OutTable is array(0 to 15) of bit; signal ParityBit: bit; constant OT: OutTable := ('1','0','0','1','0','1','1','0','0','1','1','0','1','0','0','1'); begin ParityBit <= OT(to_integer(X)); Y <= X & ParityBit; end Table;
Copyright Dr. Lizy John, The University of Texas at Austin

More on Array Types

Predefined unconstrained array types in VHDL include bit_vector and string, which are defined as follows: type bit_vector is array (natural range <>) of bit; type string is array (positive range <>) of character;

The characters in a string literal must be enclosed in double quotes. constant string1: string(1 to 29) := This string is 29 characters. A bit_vector literal may be written either as a list of bits separated by commas or as a string. For example, ('1','0','1','1','0') and "10110" are equivalent forms. The following declares a constant A that is a bit_vector with a range 0 to 5. constant A : bit_vector(0 to 5) := "101011";

Copyright Dr. Lizy John, The University of Texas at Austin

Sub Types

After a type has been declared, a related subtype can be declared to include a subset of the values specified by the type. For example, the type SHORT_WORD, which was defined earlier, could have been defined as a subtype of bit_vector:

subtype SHORT_WORD is bit_vector (15 downto 0);

Predefined subtypes POSITIVE all positive integers NATURAL 0 and positive integers

Copyright Dr. Lizy John, The University of Texas at Austin

Loops in VHDL infinite loop

The general form for an infinite loop is [loop-label:] loop sequential statements end loop [loop-label];

An exit statement of the form exit; or exit when condition; may be included in the loop. The loop will terminate when the exit statement is executed, provided that the condition is TRUE.

Copyright Dr. Lizy John, The University of Texas at Austin

Loops in VHDL for loop

The general form for a for loop is [loop-label:] for loop-index in range loop sequential statements end loop [loop-label];

Loop index cannot be changed in the loop

4 bit adder begin loop1: for i in 0 to 3 loop cout := (A(i) and B(i)) or (A(i) and cin) or (B(i) and cin); sum(i) := A(i) xor B(i) xor cin; cin := cout; end loop loop1;

Copyright Dr. Lizy John, The University of Texas at Austin

While Loop

Type of loop where loop index can be manipulated by he programmer The general form of a while loop is [loop-label:] while condition loop sequential statements end loop [loop-label];

Copyright Dr. Lizy John, The University of Texas at Austin

VHDL Functions

A function executes a sequential algorithm and returns a single value to the calling program. function rotate_right (reg: bit_vector) return bit_vector is begin return reg ror 1; end rotate_right; The general form of a function declaration is function function-name (formal-parameter-list) return return-type is [declarations] begin sequential statements -- must include return return-value; end function-name; The general form of a function call is function_name (actual-parameter-list)

Copyright Dr. Lizy John, The University of Texas at Austin

Function example code without a loop

-- This function takes a 4-bit vector -- It returns a 5-bit code with even parity function parity (A: bit_vector(3 downto 0); B: bit_vector(4 downto 0)) return bit_vector is variable parity: bit; begin parity := a(0) xor a(1) xor a(2) xor a(3)

B:= A & parity return B; end parity;


Copyright Dr. Lizy John, The University of Texas at Austin

Add Function

-- This function adds 2 4-bit vectors and a carry. --Returns 5 bit sum; Illustrates function creation and use of loop

function add4 (A,B: bit_vector(3 downto 0); carry: bit) return bit_vector is variable cout: bit; variable cin: bit := carry; variable sum: bit_vector(4 downto 0):="00000"; begin loop1: for i in 0 to 3 loop cout := (A(i) and B(i)) or (A(i) and cin) or (B(i) and cin); sum(i) := A(i) xor B(i) xor cin; cin := cout; end loop loop1; sum(4):= cout; return sum; end add4;
Copyright Dr. Lizy John, The University of Texas at Austin

Add Function Call


The total simulation time required to execute the add4 function is zero. Not even delta time is required, since all the computations are done using variables The function call is of the form add4( A, B, carry )

A and B may be replaced with any expressions that evaluate to bit_vectors with dimensions 3 downto 0, and carry may be replaced with any expression that evaluates to a bit. For example, the statement
Z <= add4(X, not Y, '1'); results in Sum = A + B + carry = X + not Y + '1'
Copyright Dr. Lizy John, The University of Texas at Austin

VHDL Procedures

The form of a procedure declaration is procedure procedure_name (formal-parameterlist) is [declarations] begin sequential statements end procedure-name; The formal-parameter-list specifies the inputs and outputs to the procedure and their types. A procedure call is a sequential or concurrent statement of the form procedure_name (actual-parameter-list);

Copyright Dr. Lizy John, The University of Texas at Austin

VHDL Procedures

Write a procedure Addvec, which will add two N-bit vectors and a carry, and return an N-bit sum and a carry. We will use a procedure call of the form Addvec ( A, B, Cin, Sum, Cout, N); where A, B, and Sum are N-bit vectors, Cin and Cout are bits, and N is an integer.

Copyright Dr. Lizy John, The University of Texas at Austin

Function returning an array


function squares(Number_arr: FourBitNumbers; length: integer) return squareNumbers is variable SN: squareNumbers; variable temp_integer: integer; begin loop1: for i in 0 to length loop temp_integer := to_integer(Number_arr(i)) * to_integer(Number_arr(i)); SN(i) := to_unsigned(temp_integer,8); end loop loop1; return SN; end squares;
Copyright Dr. Lizy John, The University of Texas at Austin

Procedure to add bit-vectors


procedure Addvec (Add1,Add2: in bit_vector; Cin: in bit; signal Sum: out bit_vector; signal Cout: out bit; n:in positive) is variable C: bit; begin C := Cin; for i in 0 to n-1 loop Sum(i) <= Add1(i) xor Add2(i) xor C; C := (Add1(i) and Add2(i)) or (Add1(i) and C) or (Add2(i) and C); end loop; Cout <= C; end Addvec;
Copyright Dr. Lizy John, The University of Texas at Austin

Parameters for Subprogram Calls


Actual Parameter Mode in1 out/inout Class constant2 signal variable signal variable3 Procedure Call expression signal variable signal variable Function Call expression signal n/a n/a n/a 3 default for

1 default mode for functions 2 default for in mode out/inout mode

Class, mode and type of each parameter must be specified Class constant, signal, variable; Mode in, out, inout ; type data type Note: Function parameter cannot be variable; return is not via in parameter
Copyright Dr. Lizy John, The University of Texas at Austin

ASSERT and report statements

The ASSERT statement checks to see if a certain condition is true, and if not causes an error message to be displayed. One form of the assert statement is: assert boolean-expression report string-expression severity severity-level;

Boolean expression is the condition being checked If condition not met, assertion violation; simulator reports it If condition true, no message

Copyright Dr. Lizy John, The University of Texas at Austin

Severity statement
severity severity-level;

4 severity levels note, warning, error, failure Include one of these to indicate the degree to which the violation affects the model Action taken for the severity level depends on the simulator If the assert clause is omitted, then the report is always made. Thus the statement: report "ALL IS WELL";

Copyright Dr. Lizy John, The University of Texas at Austin

Use of ASSERT and REPORT: Check Setup time and hold time violations of flip-flop
check: process begin wait until (Clkevent and CLK=0); assert (D'stable(setup_time)) report ("Setup time violation") severity error; wait for hold_time; assert (D'stable(hold_time)) report ("Hold time violation") severity error; end process check;
Copyright Dr. Lizy John, The University of Texas at Austin

STABLE: Attribute that returns a signal


S'STABLE [(time)]* true for the Boolean signal that is if S had no events specified time

This attribute is used in the example to check setup time and hold violation of a flip-flop.

Copyright Dr. Lizy John, The University of Texas at Austin

Test Benches
Assert and Report Statements are very useful for creating test benches Test Benches VHDL code to provide inputs to the model under test, receive outputs from model and compare with expected answer Assert statement is meaningful only for simulation Synthesizers often assume that assertion violation does not exist
Copyright Dr. Lizy John, The University of Texas at Austin