-- --------------------------------------------------------------------
--
--   File name :  logic_system.pkg_body.vhdl
--   Title     :  LOGIC_SYSTEM package ( multivalue logic system )
--   Library   :  STD
--   Author(s) :  W. Billowitch ( The VHDL Consulting Group )
--   Purpose   :  To define the declarations made in the package
--             :
--   Notes     :  
-- --------------------------------------------------------------------
--   Modification History :
-- --------------------------------------------------------------------
--   Version No:| Author:|  Mod. Date:| Changes Made:
--     v2.000   |  wdb   |   6/19/90  | DRAFT STANDARD
--     v2.100   |  wdb   |   7/16/90  | Addition of 'U' and '-' states
--     v2.200   |  wdb   |  10/08/90  | Modified 'U' propagation
--     v2.300   |  wdb   |  10/24/90  | Changed '-' to 'D', deleted attributes
-- --------------------------------------------------------------------

Library STD; -- library location of this package
PACKAGE BODY logic_system is
    -------------------------------------------------------------------    
    -- Local Types
    -------------------------------------------------------------------    
    TYPE stdlogic_1D is array (std_ulogic) of std_ulogic;
    TYPE stdlogic_table is array(std_ulogic, std_ulogic) of std_ulogic;

    -------------------------------------------------------------------    
    -- Resolution function
    -------------------------------------------------------------------    
    CONSTANT resolution_table : stdlogic_table := (
	--      ---------------------------------------------------------
	--      |  U    X    0    1    Z    W    L    H    D 	    |   |  
	--      ---------------------------------------------------------
            ( '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', '0' ), -- | 0 |
            ( 'U', 'X', 'X', '1', '1', '1', '1', '1', '1' ), -- | 1 |
            ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'Z' ), -- | Z |
            ( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'W' ), -- | W |
            ( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'L' ), -- | L |
            ( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'H' ), -- | H |
            ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'D' )  -- | D |
        );
        
    FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic IS
        VARIABLE result : std_ulogic := 'D';  -- weakest state default
    BEGIN
        IF    (s'LENGTH = 1) THEN    RETURN s(s'LOW);
        ELSE
            -- Iterate through all inputs
            FOR i IN s'RANGE LOOP
                result := resolution_table(result, s(i));
            END LOOP;
            -- Return the resultant value 
            RETURN result;
        END IF;
    END resolved;

    -------------------------------------------------------------------    
    -- Tables for Logical Operations
    -------------------------------------------------------------------    

	-- truth table for "and" function
    CONSTANT and_table : stdlogic_table := (
	--      ----------------------------------------------------
	--      |  U    X    0    1    Z    W    L    H    D         |   |  
	--      ----------------------------------------------------
            ( 'U', 'U', '0', 'U', 'U', 'U', '0', 'U', 'U' ),  -- | U |
            ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ),  -- | X |
            ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ),  -- | 0 |
            ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ),  -- | 1 |
   	        ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ),  -- | Z |
   	        ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ),  -- | W |
   	        ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ),  -- | L |
   	        ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ),  -- | H |
   	        ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' )   -- | D |
    );

	-- truth table for "or" function
	CONSTANT or_table : stdlogic_table := (
	--      ----------------------------------------------------
	--      |  U    X    0    1    Z    W    L    H    D         |   |  
	--      ----------------------------------------------------
            ( 'U', 'U', 'U', '1', 'U', 'U', 'U', '1', 'U' ),  -- | U |
	        ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ),  -- | X |
	        ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ),  -- | 0 |
	        ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ),  -- | 1 |
	        ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ),  -- | Z |
	        ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ),  -- | W |
	        ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ),  -- | L |
	        ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ),  -- | H |
	        ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' )   -- | D |
    );


	-- truth table for "xor" function
	CONSTANT xor_table : stdlogic_table := (
	--      ----------------------------------------------------
	--      |  U    X    0    1    Z    W    L    H    D         |   |  
	--      ----------------------------------------------------
            ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ),  -- | U |
	        ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ),  -- | X |
	        ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ),  -- | 0 |
	        ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ),  -- | 1 |
	        ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ),  -- | Z |
	        ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ),  -- | W |
	        ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ),  -- | L |
	        ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ),  -- | H |
	        ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' )   -- | D |
    );

	-- truth table for "not" function
	CONSTANT not_table: stdlogic_1D := 
	--  -------------------------------------------------
	--  |   U    X    0    1    Z    W    L    H    D   |
	--  -------------------------------------------------
	     ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ); 

    -------------------------------------------------------------------    
    -- Overloaded Logical Operators ( with optimizing hints )
    -------------------------------------------------------------------    

    FUNCTION "and"  ( l : std_ulogic; r : std_ulogic ) RETURN std_ulogic IS
    BEGIN
        RETURN (and_table(L, R));
    END "and";

    FUNCTION "nand" ( l : std_ulogic; r : std_ulogic ) RETURN std_ulogic IS
    BEGIN
        RETURN  (not_table ( and_table(L, R)));
    END "nand";

    FUNCTION "or"   ( l : std_ulogic; r : std_ulogic ) RETURN std_ulogic IS
    BEGIN
        RETURN (or_table(L, R));
    END "or";

    FUNCTION "nor"  ( l : std_ulogic; r : std_ulogic ) RETURN std_ulogic IS
    BEGIN
        RETURN  (not_table ( or_table( L, R )));
    END "nor";

    FUNCTION "xor"  ( l : std_ulogic; r : std_ulogic ) RETURN std_ulogic IS
    BEGIN
        RETURN (xor_table(L, R));
    END "xor";

    FUNCTION "not"  ( l : std_ulogic ) RETURN std_ulogic IS
    BEGIN
        RETURN (not_table(L));
    END "not";
    
    -------------------------------------------------------------------    
    -- Vectorized Overloaded Logical Operators
    -------------------------------------------------------------------    
    FUNCTION "and"  ( L,R : std_logic_vector ) RETURN std_logic_vector IS
        -- Note : Implementations may use variables instead of the aliases
        ALIAS LV : std_logic_vector ( 1 to L'length ) IS L;
        ALIAS RV : std_logic_vector ( 1 to R'length ) IS R;
        VARIABLE result : std_logic_vector ( 1 to L'length ) := (Others => 'X');
    begin
        if ( L'length /= R'length ) then
            assert false
            report "Arguments of overloaded 'and' operator are not of the same length"
            severity FAILURE;
        else
            for i in result'range loop
                result(i) := and_table (LV(i), RV(i));
            end loop;
        end if;
        return result;
    end "and";

    ---------------------------------------------------------------------

    FUNCTION "nand" ( L,R : std_logic_vector ) RETURN std_logic_vector IS
        -- Note : Implementations may use variables instead of the aliases
        ALIAS LV : std_logic_vector ( 1 to L'length ) IS L;
        ALIAS RV : std_logic_vector ( 1 to R'length ) IS R;
        VARIABLE result : std_logic_vector ( 1 to L'length ) := (Others => 'X');
    begin
        if ( L'length /= R'length ) then
            assert false
            report "Arguments of overloaded 'nand' operator are not of the same length"
            severity FAILURE;
        else
            for i in result'range loop
                result(i) := not_table(and_table (LV(i), RV(i)));
            end loop;
        end if;
        return result;
    end "nand";

    ---------------------------------------------------------------------

    FUNCTION "or"  ( L,R : std_logic_vector ) RETURN std_logic_vector IS
        -- Note : Implementations may use variables instead of the aliases
        ALIAS LV : std_logic_vector ( 1 to L'length ) IS L;
        ALIAS RV : std_logic_vector ( 1 to R'length ) IS R;
        VARIABLE result : std_logic_vector ( 1 to L'length ) := (Others => 'X');
    begin
        if ( L'length /= R'length ) then
            assert false
            report "Arguments of overloaded 'or' operator are not of the same length"
            severity FAILURE;
        else
            for i in result'range loop
                result(i) := or_table (LV(i), RV(i));
            end loop;
        end if;
        return result;
    end "or";

    ---------------------------------------------------------------------

    FUNCTION "nor"  ( L,R : std_logic_vector ) RETURN std_logic_vector IS
        -- Note : Implementations may use variables instead of the aliases
        ALIAS LV : std_logic_vector ( 1 to L'length ) IS L;
        ALIAS RV : std_logic_vector ( 1 to R'length ) IS R;
        VARIABLE result : std_logic_vector ( 1 to L'length ) := (Others => 'X');
    begin
        if ( l'length /= r'length ) then
            assert false
            report "Arguments of overloaded 'nor' operator are not of the same length"
            severity FAILURE;
        else
            for i in result'range loop
                result(i) := not_table(or_table (LV(i), RV(i)));
            end loop;
        end if;
        return result;
    end "nor";

    ---------------------------------------------------------------------

    FUNCTION "xor"  ( L,R : std_logic_vector ) RETURN std_logic_vector IS
        -- Note : Implementations may use variables instead of the aliases
        ALIAS LV : std_logic_vector ( 1 to L'length ) IS L;
        ALIAS RV : std_logic_vector ( 1 to R'length ) IS R;
        VARIABLE result : std_logic_vector ( 1 to L'length ) := (Others => 'X');
    begin
        if ( l'length /= r'length ) then
            assert false
            report "Arguments of overloaded 'xor' operator are not of the same length"
            severity FAILURE;
        else
            for i in result'range loop
                result(i) := xor_table (LV(i), RV(i));
            end loop;
        end if;
        return result;
    end "xor";

    ---------------------------------------------------------------------

    FUNCTION "not"  ( l : std_logic_vector ) RETURN std_logic_vector IS
        -- Note : Implementations may use variables instead of the aliases
        ALIAS LV : std_logic_vector ( 1 to L'length ) IS L;
        VARIABLE result : std_logic_vector ( 1 to L'length ) := (Others => 'X');
    begin
        for i in result'range loop
            result(i) := not_table( LV(i) );
        end loop;
        return result;
    end;

    -------------------------------------------------------------------    
    -- Conversion Tables
    -------------------------------------------------------------------    
    TYPE logic_X01_table is array (std_ulogic'low to std_ulogic'high) of X01;
    TYPE logic_UX01_table is array (std_ulogic'low to std_ulogic'high) of UX01;
    ----------------------------------------------------------
    -- Table name : cvt_to_X01
    --
    -- Parameters :
    --        in  :: std_ulogic  -- some logic value
    -- Returns    :  X01         -- state value of logic value
    -- Purpose    :  to convert state-strength to state only
    --                  
    -- Example    : if (cvt_to_X01 (input_signal) = '1' ) then ...
    --
    ----------------------------------------------------------
    CONSTANT cvt_to_X01 : logic_X01_table := (
                         'X',  -- 'U'
                         'X',  -- 'X'
                         '0',  -- '0'
                         '1',  -- '1'
                         'X',  -- 'Z'
                         'X',  -- 'W'
                         '0',  -- 'L'
                         '1',  -- 'H'
                         'X'   -- 'D'
                        );

    ----------------------------------------------------------
    -- Table name : cvt_to_UX01
    --
    -- Parameters :
    --        in  :: std_ulogic  -- some logic value
    -- Returns    :  UX01        -- state value of logic value
    -- Purpose    :  to convert state-strength to state only
    --                  
    -- Example    : if (cvt_to_UX01 (input_signal) = '1' ) then ...
    --
    ----------------------------------------------------------
    CONSTANT cvt_to_UX01 : logic_UX01_table := (
                         'U',  -- 'U'
                         'X',  -- 'X'
                         '0',  -- '0'
                         '1',  -- '1'
                         'X',  -- 'Z'
                         'X',  -- 'W'
                         '0',  -- 'L'
                         '1',  -- 'H'
                         'X'   -- 'D'
                        );
    
    -------------------------------------------------------------------    
    -- Conversion Functions
    -------------------------------------------------------------------    
    FUNCTION Convert_to_X01  ( s : std_logic_vector ) RETURN  X01_vector IS
        ALIAS SV : std_logic_vector ( 1 to s'length ) IS s;
        VARIABLE result : std_logic_vector ( 1 to s'length ) := (Others => 'X');
    BEGIN
        for i in result'range loop
            result(i) := convert_to_X01 (SV(i));
        end loop;
        return result;
    END;

    FUNCTION Convert_to_UX01 ( s : std_logic_vector ) RETURN UX01_vector IS
        ALIAS SV : std_logic_vector ( 1 to s'length ) IS s;
        VARIABLE result : std_logic_vector ( 1 to s'length ) := (Others => 'U');
    BEGIN
        for i in result'range loop
            result(i) := convert_to_UX01 (SV(i));
        end loop;
        return result;
    END;

    FUNCTION Convert_to_X01  ( s : std_ulogic ) RETURN  X01 IS
    BEGIN
        return (cvt_to_X01(s));
    END;

    FUNCTION Convert_to_UX01 ( s : std_ulogic ) RETURN UX01 IS
    BEGIN
        return (cvt_to_UX01(s));
    END;

    -------------------------------------------------------------------    
    -- Edge Detection
    -------------------------------------------------------------------    
    FUNCTION rising_edge  (SIGNAL s : std_ulogic) RETURN boolean is
    begin
        return (s'event and (convert_to_X01(s) = '1') and 
                            (convert_to_X01(s'last_value) = '0'));
    end;
--    
    FUNCTION falling_edge (SIGNAL s : std_ulogic) RETURN boolean is
    begin
        return (s'event and (convert_to_X01(s) = '0') and 
                            (convert_to_X01(s'last_value) = '1'));
    end;

END logic_system;


<div align="center"><br /><script type="text/javascript"><!--
google_ad_client = "pub-7293844627074885";
//468x60, Created at 07. 11. 25
google_ad_slot = "8619794253";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />&nbsp;</div>