Professional Documents
Culture Documents
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
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.
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)
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
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)
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.
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.
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
The carry must be converted to an integer before it can be added to the unsigned vector A + B.
Synthesizer Output
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
Synthesis Example
library IEEE; use IEEE.numeric_std.ALL; entity Q3 is port(A,B,F, CLK: in bit; D: out bit); end Q3;
Synthesis Example
library IEEE; use IEEE.numeric_bit.ALL; entity Q3 is port(A,B,F, CLK: in bit; D: out bit); end Q3;
When synthesizer generates latches, Check whether intentional latches or undesirable ones
Copyright Dr. Lizy John, The University of Texas at Austin
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
[ ] means optional
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);
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;
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;
74163 counter
74163 is available in TTL and CMOS. What does TTL stand for? What does CMOS stand for?
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
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
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.
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.
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
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;
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;
-- State Register
then -- rising edge of clock
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
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
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];
ns
delta
trigger
Var1
Var2
Var3
sum
+0
+1
10
+0
10
+1
15
10 +0 10 +1
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
+0
+1
10
+0
10
+1
+0
+1
10
+0
10
+1
Constants
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 ];
Matrices
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;
A
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
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
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
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
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";
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:
Predefined subtypes POSITIVE all positive integers NATURAL 0 and positive integers
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.
The general form for a for loop is [loop-label:] for loop-index in range loop sequential statements end loop [loop-label];
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;
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];
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)
-- 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)
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
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);
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.
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
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
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";
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
This attribute is used in the example to check setup time and hold violation of a flip-flop.
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