Advanced Modelling Techniques in VHDL

Document Sample
Advanced Modelling Techniques in VHDL Powered By Docstoc
					      Topics of the Lecture

• Packages
• USE clause
• Aliases
• Data alias
• Non-data alias
• Resolved signals
Packages
        Packages
• Method for Grouping Related
  Declarations Which Serve a Common
  Purpose
 – Set of subprograms to operate on
   particular data type
 – Set of declarations for particular model
 – Separate interface from implementation
 – Reusable
    Packages
– Unclutter rest of model
– Allows declaration of “global” signals, e.g.,
  clocks.
  • Not a generally good since behavior can
    change through means other than signals
    declared in entity interface
           Packages
• Design Unit Similar to Entity Declarations and
  Architecture Bodies
  – Can be put in library and made accessible to other units
  – Access to items declared in the package is through using
    its Selected Name
library_name.package_name.item_name
  – Aliases can be used to allow shorter names for accessing
    declared items
        Packages
• Two Components to Packages
 –Package declaration
 –Package body
  Package Declaration
• Subprograms Using Header, Implementation
  Is Hidden
  – “information hiding”


• Constants, Do Not Need to Be Initialized in
  Declaration
  – “information hiding”
  Package Declaration
• Types, Must Be Completely Specified
  – Can have variable size arrays


• Signals Must Be Completely Specified
 Package Declaration Syntax


package identifier is
    { package_declarative_item }
 end [ package ] [ identifier ] ;
      Package Declaration
          Example*
package dp32_types is
  constant unit_delay : Time := 1 ns ;
  type bool_to_bit_table is
        array ( boolean ) of bit ;
  . . .




                              *Ashenden VHDL cookbook
        Package Declaration
            Example*
function bits_to_int
 ( bits : in bit_vector ) return integer ;
function bits_to_natural
  ( bits : in bit_vector ) return natural ;
procedure int_to_bits
  ( int : in integer ;
    bits : out bit_vector ) ;
end dp32_types ;

                                   *Ashenden VHDL cookbook
  Package Body
• Not Necessary If Package Declaration Does
  Not Declare Subprograms
• May Contain Additional Declarations Which
  Are Local to the Package Body
  – Cannot declare signals in body
    Package Body
• Declared Subprograms Must Include the Full
  Declaration As Used in Package Declaration
  – Numeric literals can be written differently if same
    value
  – Simple name may be replaced by a selected name
    provided it refers to same item
 Package Body Syntax
package body identifier is
     { package_body_declarative_item }
  end [ package body ] [ identifier ] ;
Package Body Example*
package body dp32_types is

constant bool_to_bit :
 bool_to_bit_table := ( false => '0' ,
                        true => '1' ) ;
function resolve_bit_32
 ( driver : in bit_32_array ) return bit_32 is

 constant float_value : bit_32 := X"0000_0000" ;
 variable result : bit_32 := float_value ;



                                   *Ashenden VHDL cookbook
Package Body Example*
 begin
  for i in driver'range loop
   result := result or driver ( i ) ;
  end loop ;
 return result ;
end resolve_bit_32 ;




                              *Ashenden VHDL cookbook
    Library Clause
• Makes Items in a Library Available to a
  VHDL Model
• To Access Items in a Library Need to Use
  Their selected_name

 library identifier { , . . . }      ;
   Use Clause
• Tedious to Always Use an Item’s Selected
  Name

• All Items Declared in a Package or Library
  Can Be Made “Visible” Through a Use Clause
      Use Clause
• Can Be Used in Any Declarative Section

• Keyword “All” Imports All Identifiers
    Use Clause Syntax
use selected_name    { , . . . }

selected_name <=
  name . (   identifier
           | character_literal
           | operator_symbol
           | all )
 Use Clause Example*
use work.dp32_types.all ;
entity dp32 is
 generic ( Tpd : Time := unit_delay ) ;
 port ( d_bus : inout bus_bit_32 bus ;
        a_bus : out bit_32 ;
        read, write, fetch : out bit ;
    ready, phi1, phi2, reset : in bit ) ;
end dp32 ;


                              *Ashenden VHDL cookbook
Aliases
A35ases
            Aliases
• Alternative Identifier for an Item
• Improves Readability
• Allows One to Differentiate Among Identically
  Named Items in Different Packages
• Can Refer to a Single Element or Part of a
  Composite Data Type, e.g.,
alias interrupt_level is PSW(30 downto 26);
           Aliases
• Operations on Aliases Operate on
  Actual Items Except for the Following
  Attributes
  – x’simple_name
  – x’path_name
  – x’instance_name
            Aliases
• Cannot Declare Aliases for
 –Labels
 –Loop parameters
 –Generate parameters (replicates items)
  Data Alias Syntax

alias identifier
    [ : subtype_indication ] is name ;
            Data Alias
• Subtype_indication Allows for the Type to Be
  Changed
  – If scalar original
     • Direction cannot change
     • Bounds cannot change
     • Unconstrained type allowed
          Data Alias
• Subtype_indication Allows for the Type to Be
  Changed
  – If array or array slice
     • Direction can differ
     • Bounds can differ
     • Base type must remain unchanged
Non-Data Alias Syntax

alias (   identifier
        | character_literal
        | operator_symbol )
is name [ signature ] ;
    Non-Data Alias
• Alias for Enumeration Type Does Not Require
  Definition of Aliases for Enumeration Literals
  of Original

• Alias for Physical Type Retains Units Without
  Redefinition
  Non-Data Alias Syntax
• Optional Signature
  – Only for subprograms and enumeration literals
  – Overloading of identifiers may require means of
    differentiating among alternatives
    • return type does this
  – Outer [ ] are required
 Non-Data Alias Syntax
signature <=
[ [ type_mark { , . . . } ] [ return
  type_mark ] ]
   – e.g.,

alias high is std.standard.’1’ [ return
  bit ]
          Resolved
           Signals
• VHDL Requires a Function to Specify the Values
  Which Result From Tying Multiple Outputs
  Together
• Resolved Signal Includes Resolution Function
  – Inclusion of function indicates it is a resolved signal
  Resolved Signals
• Resolution Function Must Be Written for an
  Indeterminate Number of Signals Since It Is Not
  Known When Declared How Many Signals Will Be
  Connected to It.
• The Value of a Signal at a Transaction Is
  Determined by the Resolution Function Operating
  on the Multiply Connected Signals.
 Resolved Signal Syntax
subtype_indication <=
 [ resolution_function_name ]
  type_mark [ range
  ( range_attribute_name
  | simple_expression ( to | downto )
         simple_expression)
  | ( discrete_range { , . . . } ) ] ;
Resolved Signal Example*
 package MVL4 is
type MVL4_ulogic is ( ‘X’, ‘0’, ‘1’, ‘Z’
  );
type MVL4_ulogic_vector is array
   ( natural range <> ) of MVL4_ulogic ;
function resolve_MVL4
   ( contribution : MVL4_ulogic_vector )
     return MVL4_ulogic ;
                                   *Ashenden
Resolved Signal Example*

subtype MVL4_logic is
 resolve_MVL4 MVL4_ulogic ;
end package MVL4 ;



                              *Ashenden
Resolved Signal Example*
package body MVL4 is
 type table is array
    ( MVL4_ulogic ,
      MVL4_ulogic )
   of MVL4_ulogic ;
Resolved Signal Example*
constant resolution_table : table :=
  -- ‘X’    ‘0’    ‘1’    ‘Z’
  -- -------------------------
( ( ‘X’     ‘X’    ‘X’    ‘X’ ),   --   ‘X’
   ( ‘X’    ‘0’    ‘X’    ‘0’ ),   --   ‘0’
   ( ‘X’    ‘X’    ‘1’    ‘1’ ),   --   ‘1’
   ( ‘X’    ‘0’    ‘1’    ‘Z’ ) ) ;--   ‘Z’
Resolved Signal Example*
function resolve_MVL4
  ( contribution : MVL4_ulogic_vector )
 return MVL4_ulogic is
 variable result : MVL4_ulogic := ‘Z’;
Resolved Signal Example*
 begin
  for index in contribution’range loop
   result := resolution_table
     ( result, contribution ( index ) ) ;
  end loop ;
 return result ;
 end function resolve_MVL4 ;
end package body MVL4 ;
• Advanced Modeling in VHDL
• Standard Logic System
• Package Body Example
• Use of IEEE 1164 Package
           Advanced
           Modelling
          Techniques in
             VHDL
• VHDL defines only basic features to model digital devices, such
  as, simple BIT type, two types of a delay, etc.
•    more complex data types for signals must be defined for
    realistic simulation.
           Advanced Modelling
           Techniques in VHDL
•  more complex data types for signals must be defined for realistic
  simulation.
• Recall our old Example of Nand_2:
Why we need more complex
logic definition than BIT?
– we want to get more accurate simulation results,
– we use different technology and we want to simulate the
  same design in different technologies,
– real world is more complex than '0' and '1',
– more complex delays than standard VHDL models
   • inputs, output delays,
   • rising edge, falling edge delays,
   • min, max and typical delays
            A Case Example
• Std_logic_1164 defined by IEEE as a portable constructs
• Requirements:
    – support for more realistic signal modeling,
    – technology independence, allowing extensions for the future and providing support for all
      current technologies,
    – provide consistent features which facilitate logic level modeling,
    – hide the complexity of the package from the designer as much as possible, make models
      readable,
    – provide for the timing accuracy continuum, giving the modeler flexibility to choose the
      appropriate level of model accuracy.
• Intended use of the packages:
             -- access standard logic facilities
                   use ieee.Std_logic_1164.all;
                -- VHDL entity declaration
                  --
  Standard Logic System
• modeling signals with '0' and '1' simplifies the real circuit, because it
  only consider signal voltage without signals current,
   – many simulators introduce, so called, signal strength related to the signal's
     current,
   – in std_logic_1164 we will introduce the following strengths of signals:
       •   unknown,
       •   forced,
       •   weak,
       •   high impedance,
       •   don’t care.
Standard
  Logic
 System
Standard
  Logic
 System
Rising and Falling Edges
Package
 Body
Package
  Body
(cont’d)
Package
  Body
(cont’d)
Package Body (cont’d)
Use of IEEE 1164 Package

• An Example:
    VHDL Standard Operators
•   Boolean Operators
                                                for bit and bit array types
    – not, and, nand, or, nor, xor,
      xnor
                                          most types, but not “expected”
•   Comparison Operators                  behavior for non numeric types
    – =, /=, >=, >, <=, <
•   Shifting                               for bit array types
    – sll, srl, sla, sra, rol, ror
•   Arithmetic                                for numeric types
    – +, -, + (unary), - (unary), *, /,
      mod, rem, **, abs
                                            for array types
•   Concatenation
    – &
    Operator Precedence
•   The following is the order of             Operator Precedence in Extended Backus
    operator precedence                       Naur Form (EBNF)

    1. Miscellaneous: **, abs, not          expression ::= relation {and relation} | relation {or relation}
                                                    | relation {xor relation} | relation {xnor relation}
    2. Multiplying: *, /, mod, rem                  | relation [nand relation] | relation [nor relation]

    3. Sign: +, -                           relation ::= shift_expression [(= | /= | < | <= | > | >=)
                                                                 shift_expression ]
    4. Adding: +, -, &
                                            shift_expression ::= [(sll | srl | sla | sra | rol | ror)
    5. Shifting: sll, srl, sla, sra, rol,                 simple_expression]

       ror                                  simple_expression ::= [+ | -] term {(+ | - | &) term}

    6. Relational: =, /=, <, <=, >, >=      term ::= factor {(* | / | mod | rem) factor}

    7. Logical: and, or, nand, nor, xor,    factor ::= primary [** primary] | abs primary | not primary
       xnor                                 primary ::= (expression) | literal | function_call | ...
  Operator Precedence (2)
                                          expression ::= relation {and relation} | relation {or relation}
                                                       | relation {xor relation} | relation {xnor relation}
                                                       | relation [nand relation] | relation [nor relation]
--ILLEGAL!, can't mix logical operators
result <= a and b or c; --!
                                          •Logical operators are the lowest precedence.
--should be...
result <= (a and b) or c;                 Logical operators are evaluated after the rest of the
                                          expression (the relations).
--ILLEGAL!,   can't chain nand or nor
--(nand and   nor are not associative)    •Logical operators have the same precedence. This
result <= a   nand b nand c; --!
result <= a   nor b nor c;   --!          is unusual in that some languages equate and with
                                          the * operator and or with the + operator.
--maybe
result <= (a nand b) nand c;              •Since logical operators have the same precedence,
--or                                      it is impossible to mix logical operators. Because
result <= a nand (b nand c);              logical operators cannot be mixed, parentheses
                                          must used a lot.
                                          •nand and nor cannot be chained (note the use of
                                          the [] rather than {} brackets in the EBNF syntax).
                                          This is because nand and nor are not associative.
   Operator Precedence (3)
--ILLEGAL! for similar reason as logical
if a < b = false then --!
--should be
if (a < b) = false then

--this is fine                                expression ::= relation {and relation} | relation {or relation}
if a = '1' and b = '0' then
--and is the same as                                 | relation {xor relation} | relation {xnor relation}
if (a = '1') and (b = '0') then                      | relation [nand relation] | relation [nor relation]
--ILLEGAL! cannot chain shift operators
result <= a sll 2 srl 2; --!                  relation ::= shift_expression [(= | /= | < | <= | > | >=)
--this is okay                                                     shift_expression ]
if a sll 2 > 5 then
--is equivalent to
if (a sll 2) > 5 then                         shift_expression ::= [(sll | srl | sla | sra | rol | ror)
                                                            simple_expression]
--ILLEGAL, sign can’t appear in second term
result <= a + -b; --!
--but this is legal                           simple_expression ::= [+op | -op] term {(+ | - | &) term}
result <= -a + b;

--this...                                     term ::= factor {(* | / | mod | rem) factor}
result <= -a mod b;
--is the same as
result <= -(a mod b);                         factor ::= primary [** primary] | abs primary | not primary
--ILLEGAL, not allowed
result <= a ** b ** c; --!                    primary ::= (expression) | literal | function_call | ...
result <= a ** (b ** c);

--ILLEGAL
result <= a ** -b --!
--but, strangely enough, not illegal
result <= a ** abs b;
  Standard, but not VHDL std types
• Given VHDL doesn’t even contain the types that we
  most frequently use, how do we determine what
  operators are available for :
  – User defined types
  – Types from standardized packages (e.g.
    std_logic_vector..etc.)
• This issue is made more complicated by the lack of
  a dominant standard synthesis package
  – VHDL loses some benefit if code is not completely
    portable among tools.
                       Packages                  package test_parts
                                                    constant cycleW
                                                                      is
                                                                      : integer := 3;

• Packages are used to collect together
                                                    constant addrW    : integer := 22;
                                                    constant dataW    : integer := 16;

  a set of closely related sub-                     procedure generate_clock (Tperiod,
                                                                              Tpulse,
                                                                              Tphase : in time;
  programs, parts, or types.                     end package test_parts;
                                                                              signal clk : out std_logic);


• For example, std_logic_1164 is a               package body test_parts is

  package that defines four types                   procedure generate_clock ( Tperiod,
                                                                               Tpulse,
                                                                               Tphase : in time;
  (std_ulogic, std_logic,                                                   signal clk : out std_logic ) is
                                                    begin
  std_ulogic_vector, std_logic_vector)                 wait for Tphase;
                                                       loop
  as well as the operations that can                      clk <= '0', '1' after Tpulse;
                                                          wait for Tperiod;
                                                       end loop;
  be performed on them.                             end procedure generate_clock;


• A package is comprised of a package            end package body test_parts;


  header and a package body
     use work.my_components.all;

     architecture behavior of simplecircuit is   library ieee;
     signal andout1, andout2 : std_logic;        use ieee.std_logic_1164.all;
     begin                                       use work.test_parts.all;
        U6: and2 port map (a1,b1,andout1);
        U7: and2 port map (a2,b2,andout2);          .
                                                    .
        sigout <= andout1 or andout2;               .
     end behavior;
    Packages and Operator
        Overloading
                                         -------------------------------------------------------------------

• It is generally the case that the      -- overloaded logical operators
                                         -------------------------------------------------------------------

  operations that you want to             FUNCTION "and" (
                                          FUNCTION "nand" (
                                                              l
                                                              l
                                                                  :
                                                                  :
                                                                      std_ulogic; r
                                                                      std_ulogic; r
                                                                                      :
                                                                                      :
                                                                                          std_ulogic )
                                                                                          std_ulogic )
                                                                                                         RETURN UX01;
                                                                                                         RETURN UX01;
  perform on your newly                   FUNCTION "or"
                                          FUNCTION "nor" (
                                                          (   l
                                                              l
                                                                  :
                                                                  :
                                                                      std_ulogic; r
                                                                      std_ulogic; r
                                                                                      :
                                                                                      :
                                                                                          std_ulogic )
                                                                                          std_ulogic )
                                                                                                         RETURN UX01;
                                                                                                         RETURN UX01;
                                          FUNCTION "xor" (    l   :   std_ulogic; r   :   std_ulogic )   RETURN UX01;
  defined types (say                    -- function "xnor"
                                          function xnor   (
                                                              (
                                                              l
                                                                  l
                                                                  :
                                                                      : std_ulogic;
                                                                      std_ulogic; r
                                                                                      r
                                                                                      :
                                                                                          : std_ulogic
                                                                                          std_ulogic )
                                                                                                         ) return ux01;
                                                                                                         return ux01;
  std_logic_vector) are the same          FUNCTION "not" (    l   :   std_ulogic                     )   RETURN UX01;

                                          -------------------------------------------------------------------
  as the VHDL std operators.              -- vectorized overloaded logical operators
                                          -------------------------------------------------------------------

• VHDL supports “operator                 FUNCTION "and" ( l, r : std_logic_vector ) RETURN std_logic_vector;
                                          FUNCTION "and" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;

  overloading”                            FUNCTION "nand" ( l, r : std_logic_vector ) RETURN std_logic_vector;
                                          FUNCTION "nand" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;

    – multiple versions of the            FUNCTION "or"
                                          FUNCTION "or"
                                                           ( l, r : std_logic_vector ) RETURN std_logic_vector;
                                                           ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;
      operators can be available,         FUNCTION "nor"   ( l, r : std_logic_vector ) RETURN std_logic_vector;
      with the same name                  FUNCTION "nor"   ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;


    – which version is “called”
                                          FUNCTION "xor"   ( l, r : std_logic_vector ) RETURN std_logic_vector;
                                          FUNCTION "xor"   ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector;

      depends on the parameters
      and their types                             from std_logic_1164 package header

 bitwise boolean operators are overloaded for std_logic, so their behavior
 is now governed by the package body
Implementation of AND in 1164
                                           from std_logic_1164 package body
• If you want to know how a
                                  CONSTANT and_table : stdlogic_table := (
                                     --      ----------------------------------------------------
                                     --      | U     X    0    1    Z    W    L    H    -           |       |
  function works, check the          --      ----------------------------------------------------
                                             ( 'U', 'U', '0', 'U', 'U', 'U', '0', 'U', 'U' ), --    |   U   |
                                             ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), --    |   X   |
  source in the package body.                ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), --
                                             ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), --
                                                                                                    |
                                                                                                    |
                                                                                                        0
                                                                                                        1
                                                                                                            |
                                                                                                            |

• AND on two                                 ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), --
                                             ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), --
                                             ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), --
                                                                                                    |
                                                                                                    |
                                                                                                    |
                                                                                                        Z
                                                                                                        W
                                                                                                        L
                                                                                                            |
                                                                                                            |
                                                                                                            |
  std_logic_vectors works as we              ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), --
                                             ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' )   --
                                                                                                    |
                                                                                                    |
                                                                                                        H
                                                                                                        -
                                                                                                            |
                                                                                                            |
  would expect, bitwise and’ing      );

                                  …
  of the two vectors.                 FUNCTION "and" ( l,r : std_logic_vector ) RETURN std_logic_vector IS
  Metalogical and hi-Z values             -- pragma built_in SYN_AND
                                  -- pragma subpgm_id 198
                                          --synopsys synthesis_off
  are handled according to the            ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l;
                                          ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r;
  table.                                  VARIABLE result : std_logic_vector ( 1 TO l'LENGTH );
                                          --synopsys synthesis_on
                                      BEGIN
• This is the simulator model,            --synopsys synthesis_off
                                          IF ( l'LENGTH /= r'LENGTH ) THEN
                                              ASSERT FALSE
  understanding this lets you                 REPORT "arguments of overloaded 'and' operator are not of
                                       the same length"
  understand the behavior, not            ELSE
                                              SEVERITY FAILURE;

  necessarily the synthesis                   FOR i IN result'RANGE LOOP
                                                  result(i) := and_table (lv(i), rv(i));
                                              END LOOP;
  implementation. Synthesis               END IF;
                                          RETURN result;
  Implementation is typically             --synopsys synthesis_on
                                      END "and";

  the minimal combinatorial
  representation and is
  guaranteed by the tool vendor
  to match the simulation
Comparison Operators for array types
Since std_logic_1164 only overloads logical operators, we are left with the VHDL
built-in comparisons, arithmetic..etc. These don’t always behave like you expect,
because now std_logic_vector is just an array of enumerated types.
                                                            Example circuit for a < b where
                            A(2)       A(1)         A(0)    a’range is 2 downto 0 and b’range
                                                            is 3 downto 0.

                           =          =            =
                                                               '1'
           Less Than
                           <          <            <

                           B(3)       B(2)         B(1)        B(0)



• Arrays are compared                         Operator a'length < a'length = a'length >
                                                        b'length b'length b'length
  from left to right,                            <          1          0          0
                                                <=          1          1          0
  regardless of their ranges                     >          0          0          1
  or sizes! If a bit is not                     >=          0          1          1
  found that satisfies the
   Comparison Operators for array types
    Examples :
 library ieee;                                  a = “00000000” z = “1111” : altz = ‘1’, agtz = ‘0’
 use ieee.std_logic_1164.all;                   a = “1111- - - -” z = “1111” : altz = ‘0’, agtz = ‘1’
                                                a = “10111111” z = “1111” : altz = ‘1’, agtz = ‘0’
 entity test is                                 a = “00011111” z = “1111” : altz = ‘1’, agtz = ‘0’
  port (a : in std_logic_vector (7 downto 0);
       z : in std_logic_vector (3 downto 0);
       altz, agtz : out std_logic);
 end entity test;

 architecture example of test is
 begin
             altz <= '1' when a < z else '0';
             agtz <= '1' when a > z else '0';
 end architecture example;


• Arrays are compared from                       Operator a'length < a'length = a'length >
                                                           b'length b'length b'length
  left to right, regardless of                      <          1          0          0
  their ranges or sizes! If a bit is               <=          1          1          0
  not found that satisfies the                      >          0          0          1
                                                   >=          0          1          1
  condition, the result is
  determined by the lengths.
        Numerical Packages
                             std_logic_arith & numeric_std
• Problems
    – comparison operators have strange behavior on our array types
    – no arithmetic operators available for arrays of std_logic (which we definitely need)
    – shifting operators not supported (87) for std_logic_vector, and these also have some non-
      conventional behavior
• Solutions
    – Packages that define new types and overload appropriate operators
    type UNSIGNED is array (NATURAL range <>) of STD_LOGIC;
    type SIGNED is array (NATURAL range <>) of STD_LOGIC;
    – This gives us a type that represents the hardware we are building like a std_logic_vector,
      while still giving us the mathematical capabilities of a integer
• There is a cost to using these packages, and that is simulation time
    – When using integers, the simulator can before the operation as written, when using
      std_logic_arith the operation is much more complicated
    – For example, an integer multiplication working on 32-bit operands is a single operation,
      whereas the same multiplication on 32 bit arrays takes more than a thousand operations
    – This is only a concern when it affects us, therefore it is rarely a concern!
std_logic_arith & numeric_std
• Since the arrays of std_logic now represent
  numeric values
   – Operators can be defined to support the arithmetic
     operations (which the integer type provided us)…
   – The comparison operations can be overloaded to be
     numerical comparisons
   – PLUS, we can relatively easily use the bitwise logical
     operations on our numbers (unlike integers)…
   – …as well as slicing and concatenation (which are also
     not offered by integers). These are VHDL standard
     array operators, and come for free.
• Note that the shift operators are not supported
  <check this>
std_logic_arith & numeric_std



Convention Note : All of the functions in the standard
packages are defined such that a vector is always interpreted
where the left-most bit is the MSB (regardless of array range
at definition)


Reminder: although signed,unsigned,and std_logic_vector
look the same, VHDL is strongly typed, so they cannot be
interchanged without explicit conversion.
What package to use?
• Approved IEEE package : numeric_std
• Old Defacto std : std_logic_arith
   – written by Synposys before there was a standard.
   – still widely in use mostly due to inertia


• Since numeric_std is indeed a standard, it is guaranteed to be
  portable among synthesizers and simulators.
• Though std_logic_arith is fairly uniform, there are various
  implementations

• Recommendation : use approved IEEE package
             Operators defined in
                numeric_std
• Many operators are defined in the numeric_std package for signed and unsigned:
    – Comparison: =, /=, <, <=, >, >=
         • return Boolean, and work exactly as you would expect, and based on the numeric value.
           Operators are overloaded for comparing each type with itself and with integers only.
         •   function   ">"   (L,   R: UNSIGNED) return BOOLEAN;
         •   function   ">"   (L,   R: SIGNED) return BOOLEAN;
         •   function   ">"   (L:   NATURAL; R: UNSIGNED) return BOOLEAN;
         •   function   ">"   (L:   INTEGER; R: SIGNED) return BOOLEAN;
         •   function   ">"   (L:   UNSIGNED; R: NATURAL) return BOOLEAN;
         •   function   ">"   (L:   SIGNED; R: INTEGER) return BOOLEAN;

    – Arithmetic: sign -, sign +, abs, +, -, * (sign – and abs are only defined for signed)
         • Again, these are overloaded for the same combinations. Note the lack of overloading for a
           combination of signed and unsigned operands.
    – Boolean Operators: not, and, or, nand, nor, xor
         • These are only supported for types signed and unsigned with themselves. (std_logic_1164
           contains these for std_logic_vector)
    – Limited Arithmetic Operators : /, mod, rem
         • not universally synthesizeable, can be synthesized in XST (Xilinx Synthesis Technology) if left
           operand is a constant power of 2
 Comparison Operators in
     numeric_std
    Example :
 library ieee;
 use ieee.numeric_std_all;
 use ieee.std_logic_1164.all;

 entity test is
  port (a : in unsigned (7 downto 0);   a = “00000000” z = “1111” : altz = ‘1’, agtz = ‘0’
       z : in unsigned (3 downto 0);    a = “1111- - - -” z = “1111” : altz = ‘0’, agtz = ‘1’
       altz, agtz : out std_logic);     a = “10111111” z = “1111” : altz = ‘0’, agtz = ‘1’
 end entity test;                       a = “00011111” z = “1111” : altz = ‘0’, agtz = ‘1’

 architecture example of test is
 begin
   altz <= '1' when a < z else '0';
   agtz <= '1' when a > z else '0';
 end architecture example;


• Numerical values are compared regardless of size
  Resize Functions (Numeric_Std)
      function RESIZE (ARG: SIGNED; NEW_SIZE: NATURAL) return SIGNED;
      function RESIZE (ARG: UNSIGNED; NEW_SIZE: NATURAL) return UNSIGNED;
                msb              lsb
                                          library ieee;
                                          use ieee.std_logic_1164.all;
                                          use ieee.numeric_std.all;
       sign
                                          entity resizes is
                                             port (sa: in signed(7 downto 0);
                                                   sb: in signed(15 downto 0);
                                                   sa_large : out signed (15 downto 0);
                                                   sb_small : out signed (7 downto 0);
                                                   ua: in unsigned(7 downto 0);
                                                   ub: in unsigned(15 downto 0);
                                                   ua_large : out unsigned (15 downto 0);
                                                   ub_small : out unsigned (7 downto 0) );
                                          end entity resizes;

                                          architecture example of resizes is
                                          begin
                                             --signed length conversions
                                             sa_large <= resize(sa, sa_large'length);
                                             sb_small <= resize(sb, sb_small'length);

                                             --unsigned length conversions
                                             ua_large <= resize(ua, ua_large'length);
                                             ub_small <= resize(ub, ub'length);
msb                              lsb      end architecture example;

                                          -- conventional resizing could be done using slice
                                          -- sb_small <= sb(sb_small’range);
                                          -- sb_small <= sb(7 downto 0);
numeric_std Arithmetic Operators (+/-)
• The “+” and “-” preserve      library ieee;
                                use ieee.std_logic_arith.all;
                                use ieee.std_logic_1164.all;
  the length of the data        entity addition is
                                   port (a,b : in signed (7 downto 0);
  path                                   z : out signed (7 downto 0));
                                end entity addition;

   – This means that addition   architecture example of addition is
                                begin
     and subtraction wrap          --a + b could possibly wrap
                                   z <= a + b;
                                end architecture addition;
     around on overflow
   – This can be avoided by
     resizing prior to the
                                library ieee;
     operation                  use ieee.std_logic_arith.all;
                                use ieee.std_logic_1164.all;

• The “+” and “-”               entity addition is
                                   port (a,b : in signed (7 downto 0);
  operators have been                    z : out signed (8 downto 0));
                                end entity addition;

  defined so that they can      architecture example of addition is
                                begin
                                   --a + b cannot wrap, but the length has
  be used on arguments             --not been preserved
                                   z <=   resize(a,z’length)

  which are different sizes.            + resize(b, z’length);
                                end architecture addition;


   – In the case when the
                  Exa : “+” in numeric_std
                                   • “+” resizes input operands (and
function "+" (L, R: UNSIGNED) return UNSIGNED is
constant SIZE: natural := MAX(L'LENGTH, R'LENGTH);
variable L01 : UNSIGNED(SIZE-1 downto 0);

                                       takes the strength out if it
variable R01 : UNSIGNED(SIZE-1 downto 0);
begin
 if ((L'LENGTH < 1) or (R'LENGTH < 1)) then
  return NAU;
 end if;
 L01 := TO_01(RESIZE(L, SIZE), 'X');
                                       exists)
 if (L01(L01'LEFT)='X') then
   return L01;
 end if;
R01 := TO_01(RESIZE(R, SIZE), 'X');
                                   • calls local function
 if (R01(R01'LEFT)='X') then
  return R01;
 end if;
return ADD_UNSIGNED(L01, R01, '0');
                                       ADD_UNSIGNED, shown
end "+";
                                       below
                                   • ADD_UNSIGNED operates
   function ADD_UNSIGNED (L, R: UNSIGNED; C: std_logic) return
   UNSIGNED is constant L_LEFT: integer := L'LENGTH-1;
   alias XL: UNSIGNED(L_LEFT downto 0) just like you’d expect addition
                                        is L;
   alias XR: UNSIGNED(L_LEFT downto 0) is R;
                                       to 0);
   variable RESULT: UNSIGNED(L_LEFT downtooperate, LSB to MSB,
   variable CBIT: std_logic := C;
   begin                               keeping track of carry between
     for I in 0 to L_LEFT loop
       RESULT(I) := CBIT xor XL(I) xor bits.
                                        XR(I);
       CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and
   XR(I));
     end loop;
     return RESULT;
   end ADD_UNSIGNED;
         Arithmetic Ops
• Seeing this model emphasizes the simulation time
   penalty paid by using ennumerrated array types for
   arithmetic.
• Synthesis for this operation would simply be a standard
   adder implemented optimally (hopefully) for that
   particular technology
   “Wrapping” code R: required in a counter, UNSIGNED is
• function ADD_UNSIGNED (L, notUNSIGNED; C: std_logic) return since as you
   can see, “111” + “001” = “000”, just like a hardware
  constant L_LEFT: integer := L'LENGTH-1;
  alias XL: UNSIGNED(L_LEFT downto 0) is L;
   adder
  alias XR: UNSIGNED(L_LEFT downto 0) is R;
  variable RESULT: UNSIGNED(L_LEFT downto 0);
  variable CBIT: std_logic := C;
  begin
    for I in 0 to L_LEFT loop
      RESULT(I) := CBIT xor XL(I) xor XR(I);
      CBIT := (CBIT and XL(I)) or (CBIT and XR(I)) or (XL(I) and XR(I));
    end loop;
    return RESULT;
  end ADD_UNSIGNED;
numeric_std Arithmetic Operators (sign +/-, abs)
                                 library ieee;                                   Decimal     Two's

                                 use ieee.numeric_std.all;                       Number    Complement
                                 use ieee.std_logic_1164.all;                      15        0,1111

•   As noted, the sign +, sign   entity negation is
                                                                                   14        0,1110

                                                                                   13        0,1101
    -, abs, +, -, and *             port (a : in signed (7 downto 0);
                                          aneg : out signed (7 downto 0);          12        0,1100


    operators are available               aabs : out signed (7 downto 0));         11        0,1011

                                 end entity negation;                              10        0,1010

    for signed vectors, while    architecture example of negation is
                                                                                   9         0,1001

                                                                                   8         0,1000

    the +, -, and * operators    begin
                                    --if a is max neg number, then will return
                                                                                   7         0,0111


    are available for unsigned      --the same thing!                              6         0,0110


                                    aneg <= -a;                                    5         0,0101


    vectors.                        aabs <= abs a;                                 4         0,0100

                                 end architecture example;                         3         0,0011


•   The operators have been                                                        2         0,0010

                                                                                   1         0,0001

    defined so that the                                                            0         0,0000



    numbers wrap on              library ieee;
                                 use ieee.numeric_std.all;
                                                                                   -1

                                                                                   -2
                                                                                             1,1111

                                                                                             1,1110


    overflow                     use ieee.std_logic_1164.all;                      -3

                                                                                   -4
                                                                                             1,1101

                                                                                             1,1100

     – Therefore, adding 1 to    entity negation is
                                    port (a : in signed (7 downto 0);
                                                                                   -5        1,1011

                                                                                   -6        1,1010
       the most positive                  aneg : out signed (7 downto 0);
                                                                                   -7        1,1001
                                          aabs : out signed (8 downto 0));
       signed number returns     end entity negation;                              -8        1,1000

                                                                                   -9        1,0111
       the most negative         architecture example of negation is               -10       1,0110

       signed number (“01..1”    begin                                             -11       1,0101

                                    --this is a fix, but probably
       + ‘1’ => “11...1”)…
                                                                                   -12       1,0100
                                    --not neccesary                                -13       1,0011
                                    aneg <= -resize(a, 9);
     – …while adding 1 to the       aabs <= abs resize(a, 9);
                                                                                   -14       1,0010


                                 end architecture example;                         -15       1,0001

       most positive unsigned                                                      -16       1,0000


       number returns 0
numeric_std Arithmetic Operators
              (*)
• The “*” operator is an exception,
  in that it does not preserve the data
  bus size                                library ieee;
                                          use ieee.numeric_std.all;
• The result size is calculated by        use ieee.std_logic_1164.all;

  adding the sizes of the arguments       entity mult is
                                             port (a,b : in signed (7 downto 0);
• Therefore, multiplication can                    z : out signed (7 downto 0));
                                          end entity mult;
  never overflow, so resizing is not
                                          architecture example of mult is
  necessary before performing a              signal product : signed(15 downto 0);
                                          begin
  multiplication operation                   --multiply, and then resize
                                             product <= a*b;
• However, it often means that the           z <= resize(product, z’length);
  result after the multiplication will       --shorter method
                                             z <= resize(a*b, 8);
  need to be truncated by slicing or      end architecture example;
  by resizing.
numeric_std Arithmetic Operators (*)
                          library ieee;
                          use ieee.numeric_std.all;
                          use ieee.std_logic_1164.all;

                          entity mult is
                             port (a,b : in signed (7 downto 0);
                                   z : out signed (7 downto 0));
                          end entity mult;

                          architecture example of mult is
                             signal product : signed(15 downto 0);
                          begin
                             --multiply, and then resize
                             product <= a*b;
                             z <= resize(product, z’length);

                             --shorter method
                             z <= resize(a*b, 8);
                          end architecture example;


             Spartan II                                   Virtex II
# BELS                             : 99
#      GND                         : 1          Cell Usage :
#      LUT2                        : 16         # BELS                :   1
#      LUT4                        : 16         #      GND            :   1
#      MULT_AND                    : 16         # IO Buffers          :   24
#      MUXCY                       : 25         #      IBUF           :   16
#      XORCY                       : 25         #      OBUF           :   8
# IO Buffers                       : 24         # Others              :   1
#      IBUF                        : 16         #      MULT18X18      :   1
#      OBUF                        : 8
========================================
         Type Conversion Functions
              (Numeric_Std)
              function TO_INTEGER (ARG: SIGNED) return INTEGER;
              function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
              function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
              function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;

library ieee;                                      library ieee;
use ieee.std_logic_1164.all;                       use ieee.std_logic_1164.all;
use ieee.numeric_std.all;                          use ieee.numeric_std.all;

entity to_integer_demo is                          entity to_unsigned_demo is
   port (a : in unsigned(7 downto 0);                 port (value : in natural range 0 to 255;
         z : out natural range 0 to 255);                   result : out unsigned (7 downto 0));
end entity to_integer_demo;                        end entity to_unsigned_demo;

architecture example of to_integer_demo is         architecture behavior of to_unsigned_demo is
begin                                              begin

   z <= to_integer(a);                                result <= to_unsigned(value,8);

end architecture example;                          end architecture example;

                                                   -- good practice :
                                                   -- result <= to_unsigned(value, result’length);
   Type Conversion Functions
        (Numeric_Std)
 Remember : we automatically have closely related type conversion functions:

                                                library ieee;
                                                use ieee.numeric_std.all;
library ieee;                                   use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_1164.all;
                                                entity type_demo2 is
                                                   port (a : in unsigned(6 downto 0);
entity type_demo is                                      z : out signed(7 downto 0));
   port (a : in std_logic_vector(7 downto 0);   end entity type_demo2;
         z : out unsigned(7 downto 0));
end entity type_demo;                           architecture example of type_demo2 is
                                                begin
architecture example of type_demo is
begin                                                z <= ‘0’ & signed(a);
   z <= unsigned(a);                            end architecture example;
end architecture example;                       --   we add an extra bit to preserve numeric
                                                --   representation
                                                --   NOTHING special is done here, we are simply
                                                --   telling the compiler to interpret the bits
                                                --   in the array as a different type
                Constants
constant values of signed and unsigned (since they are array’s of std_logic) can
be represented by string values :

Assignments :

z <= “00000000”; -- MSB on left… must be exactly right length
z <= (others => ‘0’); -- avoid this using aggregate

Bit String Literals :
          VHDL 87 – Available only to arrays of type bit.
          VHDL 93 – All character array types that contain ‘0’ and ‘1’
                     (e.g. std_logic, signed, unsigned…)

x <= B”0000_0000_1111”; -- B = Binary, underscores optional
x <= O”00_17”; -- O = Octal
x <= X”00F”;
Arithmetic with Constants

                                         mixing types by expressing the constant
                                         as an integer is often more clear
library ieee;                           library ieee;
use ieee.numeric_std.all;               use ieee.numeric_std.all;
use ieee.std_logic_1164.all;            use ieee.std_logic_1164.all;


entity increment is                     entity increment is
   port (a : in signed(7 downto 0);        port (a : in signed(7 downto 0);
         z : out signed(7 downto 0));            z : out signed(7 downto 0));
end entity increment;                   end entity increment;

architecture example of increment is    architecture example of increment is
begin                                   begin

   z <= a + “1”;                           z <= a + 1;

end architecture example;               end architecture example;
Example : Comparison Operators
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity compare is
   port (a : in signed (15 downto 0);
         negative : out std_logic);
end entity compare;

architecture example of compare is
begin
   negative <= ‘1’ when a<0 else ‘0’;
end architecture example;




library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
                                                      Note the use of the to_signed
entity max   is
   port (a   : in signed (15 downto 0);               function when copying the integer
         b   : in natural;
         c   : out signed (15 downto 0));                 to
end entity   max;
                                                      signal c. Although the functions
architecture example of max is                            are
begin
   c <= a when (a > b) else to_signed(b, c'length);   overloaded, signal assignments still
end architecture example;
                                                          are
                                                      strongly typed.
     VHDL’93 built-in Shift
         Functions
•   a(4 downto 0) sll 2 == a(2 downto 0) & “00”
•   a(4 downto 0) srl 2 == “00” & a(4 downto 2)
•   a(4 downto 0) sla 2 == ?
•   a(4 downto 0) sra 2 == ?
•   a(4 downto 0) rol 2 == a(2 downto 0) & a(4 downto 3)
•   a(4 downto 0) ror 2 == a(1 downto 0) & a(4 downto 2)


for bit vectors…

numeric_std overloads sll, srl, rol, ror for signed and unsigned types
also available (especially in ’87 synthesizers) as shift_left(), shift_right(),
rotate_left(), and rotate_right()
 Shift Functions for numeric_std
                                                      msb                       lsb
                                                                                      0 0 0 0


• Two shift operations are available for
  std_logic_arith, sll (shift_left) and srl                          unsigned)
                                                     sll (signed andand Signed
                                                           Unsigned
  (shift_right).                                              shift-left (shl
• The sll and srl functions each take two                      msb                      lsb
  arguments, the first begin the value,             0 0 0 0

  signal, or variable to shift, and the
  second being an unsigned value
  specifying how far to shift the value                         srl (unsigned)
                                                                Unsigned shift-right (shr)
   – Note that for synthesis the shift value must
     be a constant value because the synthesis                msb                       lsb
     interpretation of a shift is a hardwired
     rearrangement of the bits of not anymore!
                                     the bus
   – z <= shift_left(a,4);
   – z <= a sll 4;
                                                                 Signed shift-right (shr)
                                                                srl (signed)
        Barrel Shifter
                                           Synthesizing Unit <test>.
library IEEE;
                                             Related source file is C:\…
use IEEE.STD_LOGIC_1164.ALL;                 Found 8-bit shifter logical left for signal <sh>.
use IEEE.numeric_std.all;                    Summary:
                                                       inferred 1 Combinational logic shifter(s).
entity test is                             Unit <test> synthesized.
  Port ( norm : in unsigned(7 downto 0);
        sh : out unsigned(7 downto 0);     =====================================
                                           HDL Synthesis Report
        num : in natural range 0 to 5);
end test;                                  Macro Statistics
                                           # Logic shifters              :1
architecture Behavioral of test is          8-bit shifter logical left   :1

begin                                      =====================================

 sh <= norm sll num;

end Behavioral;
Boolean Operators
• Boolean operators (not, and nand, or, nor, xor, xnor) for std_logic_vectors:
    – The boolean operation is performed bit-by-bit (positionally) on the two vectors
    – Each vector must have the same ‘length (but not neccesarily the same ‘range)
• In Numeric_Std supported for signed and unsigned
    – SHOULD be the same length




  a : signed(7 downto 0);                   10011110               XST synthesis results
  b : signed(6 downto 0);                    1111111
  c : signed(15 downto 0));      1111111110011110


  c <= a and b;                    Simulation produces “Run-Time Error”
STD_LOGIC_ARITH

   std_logic_unsigned
    std_logic_signed
 Boolean Operators
• Boolean operators (not, and nand, or, nor, xor, xnor) for std_logic_vectors:
    – The boolean operation is performed bit-by-bit (positionally) on the two vectors
    – Each vector must have the same ‘length (but not neccesarily the same ‘range)

• Surprisingly, the boolean operators are not supported for std_logic_arith
    – This can be circumvented by type converting signed or unsigned vectors to
      std_logic_vectors, and then using the boolean operators available (remember
      that type conversion are available for closely related types.

    – As an example, consider performing a masking operation on an signed value:
        • z <= a when signed(std_logic_vector(c) and “00001111”) /= “0” else b;

    – Note that the string “00001111” is implicity assumed to be a std_logic_vector,
      and that the “0” does not need to be the same length as the resultant signed
      value because the signed comparisons are defined for different length vectors.
                    Type conversions
All functions in the form
“conv_type” where type                              Argument      Second
is the format to convert       Function Name           Type      Argument?        Result Type
to.                         conv_integer              integer        no              integer
No second argument          conv_integer              signed         no              integer
because the size of         conv_integer             unsigned        no              integer
the integer type is         conv_integer            std_ulogic       no              integer
fixed                       conv_unsigned             integer       yes            unsigned
                            conv_unsigned             signed        yes            unsigned
                            conv_unsigned            unsigned       yes            unsigned
Functions that              conv_unsigned           std_ulogic      yes            unsigned
take and return             conv_signed               integer       yes              signed
the same type               conv_signed               signed        yes              signed
are used as                 conv_signed              unsigned       yes              signed
resize functions            conv_signed             std_ulogic      yes              signed
                            conv_std_logic_vector     integer       yes         std_logic_vector
                            conv_std_logic_vector     signed        yes         std_logic_vector
                            conv_std_logic_vector    unsigned       yes         std_logic_vector
                            conv_std_logic_vector   std_ulogic      yes         std_logic_vector

                Note that there are not
                conversion functions from                  Gives the size of the
                unsigned./signed to                        array to be created, must
                std_logic_vector                           be constant for synthesis
std_logic_arith: Resize Functions
                                           library ieee;
                                           use ieee.std_logic_arith.all;
                                           use ieee.std_logic_1164.all;
                   msb             lsb

                                           entity resizes is
                                              port (sa: in signed(7 downto 0);
                                                    sb: in signed(15 downto 0);
          sign                                      sa_large : out signed (15 downto 0);
                                                    sb_small : out signed (7 downto 0);
                                                    ua: in unsigned(7 downto 0);
                                                    ub: in unsigned(15 downto 0);
                                                    ua_large : out unsigned (15 downto 0);
                                                    ub_small : out unsigned (7 downto 0) );
                                           end entity resizes;

                                           architecture example of resizes is
                                           begin
                                              --signed length conversions
 msb                               lsb
                                              sa_large <= conv_signed(sa, sa_large'length);
                                              sb_small <= conv_signed(sb, sb_small'length);

                                              --unsigned length conversions
                                              ua_large <= conv_unsigned(ua, ua_large'length);
                                              ub_small <= conv_unsigned(ub, ub'length);

                                              --would be the same as
                                              ua_large <= (ua’range => '0') & ua;
                                              ub_small <= ub(ub_small'range);
                                           end architecture example;




 For example:
 “1000000000000001” (-32767) => “00000001” (+1)
              Constant Values and Type
                     Ambiguity
•   Constant values of signed and unsigned types can be
    represented by string values
     –   Z <= “00000000”;
     –   Z <= X”00”;
     –   Z <= (others => ‘0’);                                         library ieee;
                                                                       use ieee.std_logic_1164.all;
     –   Z <= conv_unsigned(‘0’, 8);                                   use ieee.std_logic_arith.all;
•   When adding a signal to a constant value, there is no
    need to match the size of the arguments, since the                 entity increment is
                                                                          port (a : unsigned (7 downto 0);
    functions can take operators of different lengths                           z : unsigned (7 downto 0));
•   Due to the different permutations of additions possible            end;

    for signed and unsigned vectors (because of the                    architecture behavior of increment is
    extensive overloading), type ambiguity can occur                      --ERROR, type abiguity, the compiler
                                                                          --is not able to resolve this
•   This is resolved by type qualification                                z <= a + "1";
     –   When there is ambiguity in the model (that is there are          --we can perform a type qualification
         several different values that the analyzer could choose),        --to solve the problem
         type qualification informs the analyzer which to choose          z <= a + unsigned'("1");

     –   A type qualifier consists of the name of the expected type,      --or we can add a '1', this is
         a tick (i.e. a single quote mark), and the expression being      --intepreted as a std_ulogic '1',
                                                                          --which the “+” for which the unsigned
         resolved enclosed in parentheses.                                --and signed types are overloaded
                                                                          z <= a + '1';
                                                                       end architecture increment;
std_logic_signed and std_logic_unsigned
 library IEEE;
 use IEEE.std_logic_1164.all;
 use IEEE.std_logic_arith.all;

 package STD_LOGIC_UNSIGNED is

     function   "+"(L:   STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
     function   "+"(L:   STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR;
     function   "+"(L:   INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;                  These functions define the
     function   "+"(L:   STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR;
     function   "+"(L:   STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;                unsigned operations for
                                                                                                 std_logic_vectors
     function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
     function "-"(L: STD_LOGIC_VECTOR; R: INTEGER) return STD_LOGIC_VECTOR;
     function "-"(L: INTEGER; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;
     function "-"(L: STD_LOGIC_VECTOR; R: STD_LOGIC) return STD_LOGIC_VECTOR;
     function "-"(L: STD_LOGIC; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR;                    All functions in std_logic_arith are
     .
     .                                                                                           overloaded such that they can be
     .                                                                                           used on std_logic_vectors, treated
     function "<"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return BOOLEAN;
     function "<"(L: STD_LOGIC_VECTOR; R: INTEGER) return BOOLEAN;                               as unsigned of course
     function "<"(L: INTEGER; R: STD_LOGIC_VECTOR) return BOOLEAN;
     .
     .
     .
  function CONV_INTEGER(ARG: STD_LOGIC_VECTOR) return INTEGER;
     .
                                                                                           Note how the +, -, <,
     .                                                                                     operators can be
     .
 end STD_LOGIC_UNSIGNED;                                                                   overloaded.
 package body STD_LOGIC_UNSIGNED is

  function "+"(L: STD_LOGIC_VECTOR; R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
         -- pragma label_applies_to plus                                                   The conversion functions
         constant length: INTEGER := maximum(L'length, R'length);                          available for closely related
         variable result : STD_LOGIC_VECTOR (length-1 downto 0);
     begin                                                                                 types are used to convert to
         result := UNSIGNED(L) + UNSIGNED(R);-- pragma label plus
         return   std_logic_vector(result);                                                unsigned, then the unsigned
     end;                                                                                  operations are used.
     .
     .
     .
  Overview / Suggestions
• Use Numeric_Std
• Force yourself to use some of the nice features when
  you are dealing with numbers, code will be much
  more readable and compact
  –   mixing types
  –   mixing sizes
  –   using shifting operators and type conversions
  –   represent constants in a natural fashion (I.e. decimal
      integers or bitstring literals)
                     Examples
                                               library ieee;
                                               use ieee.numeric_std.all;
                                               use ieee.std_logic_1164.all;
signal clk : std_logic;
signal data_in : unsigned(15 downto 0);
                                               entity test is
signal shiftreg : unsigned(15 downto 0);
                                                port (a : in std_logic_vector (3 downto 0);
signal load : std_logic;
                                                     dec : out std_logic_vector (15 downto 0));
                                               end entity test;
…
process (clk)
                                               architecture example of test is
begin
  if rising_edge(clk) then
                                               begin
     if load = ‘1’ then shiftreg <= data_in;
     else shiftreg <= shiftreg sll 1;
                                               process(a)
  end if;
                                               begin
end process;
                                                 dec <= (others => '0');
                                                 dec(to_integer(unsigned(a))) <= '1';
                                               end process;

                                               end architecture example;
                 Sources
• Krzysztof Kuchcinski

• K. J. Hintz

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:7
posted:9/20/2012
language:English
pages:96