DATA TYPES
A.G.Rao
IEEE Packages
IEEE defined a 9 valued logic system
IEEE developed two packages for this
system
STD_LOGIC_1164.VHD
Defines the basic value system and associated
functions
Used as is by vendors
NUMERIC_STD.VHD
Provides overloaded arithmetic and other operators
for synthesis
Vendors have developed their own versions of this
Synopsys Packages
Packages:
STD_LOGIC_1164.VHD
STD_LOGIC_ARITH.VHD
STD_LOGIC_SIGNED.VHD
STD_LOGIC_UNSIGNED.VHD
STD_LOGIC_MISC.VHD
STD_LOGIC_TEXTIO.VHD
Source location
$SYNOPSYS/packages/IEEE/src/*.vhd
STD_LOGIC_1164 - Logic Values
IEEE Standard
type STD_ULOGIC is ( ‘U’,-- Uninitialized
‘X’,-- Forcing Unknown
‘0’ ,-- Forcing 0
‘1’, -- Forcing 1
‘Z’,-- High Impedance
‘W’,-- Weak Unknown
‘L’,-- Weak 0
‘H’,-- Weak 1
‘-’,-- Don’t care
);
Strengths
Need to model bus contention
Logic values have strength
0 strong zero; 1 strong one
L weak zero; H weak one
Models the effect of source impedance
Suppose R is the resolution function, then strong
dominates weak, i.e.
0RH=HR0=0
1 RL= LR1=1
Unknown Values
X: value is 0 or 1 W: value is L or H
X and W are unknown values that arise from:
Bus contention, i.e. resolving opposite values of the
same strength yields unknowns of that strength
0 R 1 = 1 R 0 = X LR H = H R L= W
error conditions, e.g, a flip flop has an unknown state
Strength and weakness applied among values and
unknowns also, e.g.:
L R X = X, 1 R W = 1
Uninitialized Value (U)
Left most value of the type, thus the default
initialization value.
Used to model initialization of sequential
circuits:
Initial state of the circuit is U
Does the logic change this state to a 0 or a 1? If
not, the logic is not correctly designed
Z and ‘-’
Z represents high impedance, i.e., the output of
a tri-state buffer that is turned off.
- represents a don’t care
synthesis: represents a logic don’t care that can be
used for logic minimization
simulation: acts like an X, is converted to an X when
operated on.
Resolution
CONSTANT resolution_table : stdlogic_table := (
-- ---------------------------------------------------------
-- | U X 0 1 Z W L H - | |
-- ---------------------------------------------------------
( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
( 'U', 'X', '0', '1', 'W', 'W', 'W','W', 'X' ), -- | W |
( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
( 'U', 'X', 'X', 'X', 'X', 'X', 'X', ’ X', 'X' ) -- | - |
);
STD_LOGIC Definition
-------------------------------------------------------------------
-- *** industry standard logic type ***
-------------------------------------------------------------------
SUBTYPE std_logic IS resolved std_ulogic;
-------------------------------------------------------------------
-- unconstrained array of std_logic for use
in declaring signal arrays
-------------------------------------------------------------------
TYPE std_logic_vector IS
ARRAY ( NATURAL RANGE <>) OF std_logic;
Resolution Function - Resolved
FUNCTION resolved ( s : std_ulogic_vector )
RETURN std_ulogic IS
VARIABLE result : std_ulogic := 'Z'; -- weakest state default
BEGIN
-- the test for a single driver is essential otherwise the
-- loop would return 'X' for a single driver of '-' and that
-- would conflict with the value of a single driver unresolved
-- signal.
IF (s'LENGTH = 1) THEN RETURN s(s'LOW);
ELSE
FOR i IN s'RANGE LOOP
result := resolution_table(result, s(i));
END LOOP;
END IF;
RETURN result;
END resolved;
Common Subtypes
SUBTYPE X01 IS resolved std_ulogic RANGE 'X' TO '1';
-- ('X','0','1')
SUBTYPE X01Z IS resolved std_ulogic RANGE 'X' TO 'Z';
-- ('X','0','1','Z')
SUBTYPE UX01 IS resolved std_ulogic RANGE 'U' TO '1';
-- ('U','X','0','1')
SUBTYPE UX01Z IS resolved std_ulogic RANGE 'U' TO 'Z';
-- ('U','X','0','1','Z')
Overloaded Operators
For STD_ULOGIC, STD_LOGIC,
STD_ULOGIC_VECTOR and
STD_LOGIC_VECTOR
Operators
and nand
or nor
not
xor xnor
Type Conversions
FUNCTION To_bit ( s : std_ulogic ; xmap : BIT := '0' )
RETURN BIT;
FUNCTION To_bitvector ( s : std_logic_vector
; xmap : BIT := '0' ) RETURN BIT_VECTOR;
FUNCTION To_StdULogic ( b : BIT )
RETURN std_ulogic;
FUNCTION To_StdULogicVector ( b : BIT_VECTOR )
RETURN std_ulogic_vector;
Type Conversions
FUNCTION To_StdLogicVector ( b : BIT_VECTOR )
RETURN std_logic_vector;
FUNCTION To_StdLogicVector ( s : std_ulogic_vector )
RETURN std_logic_vector;
FUNCTION To_StdULogicVector ( s : std_logic_vector )
RETURN std_ulogic_vector;
Example of Type Conversion
FUNCTION To_StdLogicVector ( b : BIT_VECTOR )
RETURN std_logic_vector IS
ALIAS bv : BIT_VECTOR ( b'LENGTH-1 DOWNTO 0 ) IS b;
VARIABLE result : std_logic_vector ( b'LENGTH-1 DOWNTO 0 );
BEGIN
FOR i IN result'RANGE LOOP
CASE bv(i) IS
WHEN '0' => result(i) := '0';
WHEN '1' => result(i) := '1';
END CASE;
END LOOP;
RETURN result;
END;
The Other Way
FUNCTION To_bitvector( s : std_ulogic_vector ; xmap : BIT := '0’)
RETURN BIT_VECTOR IS
ALIAS sv : std_ulogic_vector ( s'LENGTH-1 DOWNTO 0 ) IS s;
VARIABLE result : BIT_VECTOR ( s'LENGTH-1 DOWNTO 0 );
BEGIN
FOR i IN result'RANGE LOOP
CASE sv(i) IS
WHEN '0' | 'L' => result(i) := '0';
WHEN '1' | 'H' => result(i) := '1';
WHEN OTHERS => result(i) := xmap;
END CASE;
END LOOP;
RETURN result;
END;
Edge Detection Functions
FUNCTION rising_edge (SIGNAL s : std_ulogic)
RETURN BOOLEAN IS
BEGIN
RETURN (s'EVENT AND (To_X01(s) = '1') AND
(To_X01(s'LAST_VALUE) = '0'));
END;
FUNCTION falling_edge (SIGNAL s : std_ulogic)
RETURN BOOLEAN IS
BEGIN
RETURN (s'EVENT AND (To_X01(s) = '0') AND
(To_X01(s'LAST_VALUE) = '1'));
END;
Overloading Arithmetic Operators
Want to make common arithmetic (+,-,*,/)
operators available for STD_LOGIC
Want to have relational operators work with
operands that have compatible types
Packages
Signed - twos complement arithmetic only
Defined by SYNOPSYS
Unsigned - unsigned arithmetic only
Defined by SYNOPSYS
Arithmetic -either two's complement or unsigned
Defined by IEEE, modified by vendors as necessary
Binary Number Interpretation
11111111 STD_LOGIC_VECTOR
Two's Complement Unsigned
-1 255
Packages
STD_LOGIC_UNSIGNED and
STD_LOGIC_SIGNED
SIGNED & UNSIGNED - Purpose
Define various arithmetic functions for signals,
variables, and ports defined as type
std_logic_vector only.
The packages provide the following arithmetic
functions:
std_logic_signed - Declares signed (2's-complement)
arithmetic functions.
std_logic_unsigned - Declares unsigned arithmetic
functions.
selecting the package forces the type of arithmetic
Cannot use both in the same entity-architecture pair
SIGNED & UNSIGNED - Features
The interpretation comes from inference.
STD_LOGIC_VECTOR by itself does not have
any “numerical” value
Defined only for arithmetic operations
Logical operators follow the standard rules and is
not a part of arithmetic
You don’t do logical operations with numbers anyway
Advantages
Using the std_logic_vector type and these
packages for arithmetic eliminates the need
for you to do type casting, reducing the
potential for errors in your code
In addition, consistent use of the
std_logic_vector type improves the readability
of your code
One of the operands for the arithmetic
operators can be an integer
Arithmetic Operations
Unary: negation and absolute value in signed
package
Binary: + ,- ,*, /
operands (mixed) : std_logic_vector, integer, and
std_logic
result: std_logic_vector
Relational: =, /=,<=, >=,<, >
operands (mixed) : std_logic_vector & integer
result: boolean
Using std_logic_signed for 2's Complement
Arithmetic
Change to unsigned
library IEEE;
use IEEE.std_logic_1164.all; to get that type of
use IEEE.std_logic_signed.all;.
arithmetic
entity ADD_TREE_SIGNED is
port ( A, B, C: in std_logic_vector (7 downto 0);
SUM : out std_logic_vector (7 downto 0));
end ADD_TREE_SIGNED;
architecture BEHAVIORAL of ADD_TREE_SIGNED is
begin
SUM <= A + B + C; --This is now 2's-
--complement addition
end BEHAVIORAL;
Cautions
Defined by SYNOPSYS
Migration to another vendor is difficult
Different function names
Different operations for the same function
Interpreting a vector is unnatural
What are the numeric datatypes defined for?
Readability at the expense of portability
Best Avoided
STD_LOGIC_ARITH (By Synopsys)
type UNSIGNED is array (NATURAL range <>) of
STD_LOGIC;
type SIGNED is array (NATURAL range <>) of
STD_LOGIC;
Overloaded + - * /
Operand Type: signed, unsigned, integers,
and std_ulogic
Returned Type: signed, unsigned, and
std_logic_vector
Must type cast std_logic_vectors to signed or
unsigned to use them
Can do both signed and unsigned arithmetic
with this package
Don’t mix std_logic_arith with
std_logic_(un)signed packages
Advantages and Disadvantages
Advantages
All typecasts are done explicitly
Arithmetic for std_logic_vector should always be done
by typecasting to SIGNED or UNSIGNED datatype
Disadvantages
Poor readability
Synopsys has its own implementation of IEEE 1164
and hence not fully portable
Some functions have different names
Synthesis
If you choose signed and unsigned packages,
stick with Synopsys for synthesis
These packages are not even defined by other
vendors
IEEE’s standard package numeric_std is used by all
the other vendors
If you use arith package, remember that it is not a
standardized version in Synopsys
Synthesis Tips
Integers can be synthesized
Ideal way is to use numerics for all operations
and typecast to std_logic whenever needed
Intent will be clear
Poor readbility
Integer arithmetic will result in different hardware
than SLV (Standard Logic Vector) arithmetic
Type conversion functions are vendor dependent
Extra hardware too, if you don’t aggressively optimize