220 likes | 460 Views
Subprogram declaration Subprogram body Package declaration Package body Resolution function. Subprogram overloading Subprogram return values and types Type casting and type qualification Exercises. Chapter 6 Subprograms & Packages. Subprogram declaration. Subprogram_declaration::=
E N D
Subprogram declaration Subprogram body Package declaration Package body Resolution function Subprogram overloading Subprogram return values and types Type casting and type qualification Exercises Chapter 6 Subprograms & Packages EE514
Subprogram declaration Subprogram_declaration::= procedure name[(interface_list)]| function name[(interface_list)] return type-mark; VHDL Syntax (IEEE Std 1076-1987) check : http://mikro.e-technik.uni-ulm.de/vhdl/vhdl87_syntax.html EE514
Subprogram declaration interface_list::=interface_declaration{;interface_declaration} interface_declaration::= [constant] identifier_list:[in] subtype_indication [:=static_expression] [signal] identifier_list:[mode] subtype_indication[bus] [:=static_expression]| [variable] identifier_list:[mode]subtype_indication [:=static_expression] mode::=in|out|inout|buffer|linkage EE514
Subprogram declaration EE514
Subprogram body Subprogram_body::= subprogram_declaration is subprogram_declarative_part begin sequential statements end [procedure identifier or function designator]; EE514
entity FACT is end FACT; architecture RTL of FACT is function FACTORIAL (constant N : in integer) return integer is begin if (N = 1) then return 1; elsif (N > 1) and (N < 10) then return N * FACTORIAL (N - 1); else assert FALSE report "0 < N < 10 is not true" severity NOTE; return 0; end if; end FACTORIAL; signal NUM, RESULT : integer; begin RESULT <= FACTORIAL (NUM); end RTL; Subprogram body EE514
Package declaration Package_declaration::= package identifier is package_declarative_part end[identifier]; Package declarative part may consist of subprogram declaration, type, subtype, constant, signal, file, alias, component, and attribute declarations, attribute and disconnect specification, and use clause. EE514
Package declaration package_body::= package body identifier is package_body_declarative_part end[identifier]; Package body defines bodies of subprograms or values of deferred constants declared in the package declaration EE514
Package declaration package PACK1164 is 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 type std_ulogic_vector is array ( NATURAL RANGE <> ) of std_ulogic; function resolved ( s : std_ulogic_vector ) RETURN std_ulogic; subtype UX01 is resolvedstd_ulogic RANGE 'U' TO '1'; subtype std_logic is resolved std_ulogic; type std_logic_vector is array ( NATURAL RANGE <>) of std_logic; function "and" ( l : std_ulogic; r : std_ulogic ) RETURN UX01; function "and" ( l, r : std_logic_vector ) RETURN std_logic_vector; function "and" ( l, r : std_ulogic_vector ) RETURN std_ulogic_vector; end PACK1164; EE514
Resolution function library IEEE; use IEEE.std_logic_1164.all; entity DRIVE2 is port ( A, B, A_ENn, B_ENn : in std_logic; Y : out std_logic); end DRIVE2; architecture RTL of DRIVE2 is begin Y <= A when A_ENn = '0' else 'Z'; Y <= B when B_ENn = '0' else 'Z'; end RTL; EE514
Resolution function ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | - | ); function resolved ( s : std_ulogic_vector ) RETURN std_ulogic IS variable result : std_ulogic := 'Z'; -- weakest state default begin 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; package body PACK1164 is type stdlogic_1d is array (std_ulogic) of std_ulogic; type stdlogic_table is array (std_ulogic, std_ulogic) of std_ulogic; 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 | EE514
A A_ENn B B_ENn Y ---H--- --------L-------- Z Resolution function architecture RTL of DRIVE2 is begin Y <= A when A_ENn = '0' else 'Z'; Y <= B when B_ENn = '0' else 'Z'; end RTL; Notice that initial drivers for Y are Z EE514
Subprogram overloading constant and_table : stdlogic_table := ( -- ---------------------------------------------------- -- | U X 0 1 Z W L H - | | -- ---------------------------------------------------- ( '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' ) -- | - | ); function "and" ( l : std_ulogic; r : std_ulogic ) RETURN UX01 is begin RETURN (and_table(l, r)); end "and"; EE514
Subprogram overloading Aliases are used to normalize array bonds function "and" (l,r : std_logic_vector ) RETURN std_logic_vector is 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 ); begin if ( l'LENGTH /= r'LENGTH ) then assert FALSE report "arguments of '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 "and" ( l,r : std_ulogic_vector ) RETURNstd_ulogic_vector is alias lv : std_ulogic_vector ( 1 TO l'LENGTH ) is l; alias rv : std_ulogic_vector ( 1 TO r'LENGTH ) is r; variable result : std_ulogic_vector ( 1 TO l'LENGTH ); begin if ( l'LENGTH /= r'LENGTH ) then assert FALSE repor "arguments of '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"; end PACK1164; Changed from logic to ulogic EE514
Subprogram overloading package SUBPROG is procedure MUX21( signal SEL : in bit; signal DIN0 : in bit; signal DIN1 : in bit; signal DOUT : out bit); procedure MUX21( signal SEL : in bit; signal DIN0 : in bit_vector; signal DIN1 : in bit_vector; signal DOUT : out bit_vector); end SUBPROG; package body SUBPROG is procedure MUX21( signal SEL : in bit; signal DIN0 : in bit; signal DIN1 : in bit; signal DOUT : out bit) is begin case SEL is when '0' => DOUT <= DIN0; when others => DOUT <= DIN1; end case; end MUX21; procedure MUX21( signal SEL : in bit; signal DIN0 : in bit_vector; signal DIN1 : in bit_vector; signal DOUT : out bit_vector) is begin case SEL is when '0' => DOUT <= DIN0; when others => DOUT <= DIN1; end case; end MUX21; end SUBPROG; EE514
Subprogram return values & types architecture RTL of SUBRETN is begin C <= INV(A)(2 to 4); LA <= C(C'left); RA <= C(C'right); RB <= INV(B)(4); LB <= INV(B)(1); end RTL; architecture ORDER of SUBRETN is begin C <= INV(A)(3 downto 1); end ORDER; architecture BOUND of SUBRETN is begin LB <= INV(A)(0); end BOUND; library IEEE; use IEEE.std_logic_1164.all; entity SUBRETN is signal A : std_logic_vector(7 downto 4); signal B : std_logic_vector(0 to 3); signal C : std_logic_vector(2 downto 0); signal LB, RB, LA, RA : std_logic; function INV (DIN : std_logic_vector) return std_logic_vector is variable result : std_logic_vector(1 to DIN'length); begin result := not DIN; return result; end INV; end SUBRETN; Errors- since range does not match the type of return value EE514
Simulation for RTL of SUBRETN architecture RTL of SUBRETN is begin C <= INV(A)(2 to 4); LA <= C(C'left); RA <= C(C'right); RB <= INV(B)(4); LB <= INV(B)(1); end RTL; EE514
Type casting and type qualification Type UNSIGNED and operator “+” declared in package std_logic_arith as follows type UNSIGNED is array (NATURAL range <>)of STD_LOGIC; function “+” (L: UNSIGNED; R: USIGNED) return STD_LOGIC_VECTOR; type casting can convert types and requires a single quote after type mark EE514
Type casting and type qualification library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; entity CONVTYPE is port ( RSTn, CLK : in std_logic; CNTR4 : out std_logic_vector(3 downto 0)); end CONVTYPE; architecture RTL of CONVTYPE is signal CNTR4_FF : std_logic_vector(3 downto 0); begin CNTR4 <= CNTR4_FF; p0 : process (RSTn, CLK) begin if (RSTn = '0') then CNTR4_FF <= std_logic_vector'("0000"); elsif (CLK'event and CLK = '1') then CNTR4_FF <=unsigned’(CNTR4_FF) + unsigned'("0001"); end if; end process; end RTL; EE514