---------------------------------------------------------------- -- Chapter 12 Generics ---------------------------------------------------------------- ---------------------------------------------------------------- -- 12.1 Generic Constants ---------------------------------------------------------------- -- Page 366 entity and2 is generic ( Tpd : time ); port ( a, b : in bit; y : out bit ); end entity and2; architecture simple of and2 is begin and2_function : y <= a and b after Tpd; end architecture simple; -- Page 367 gate1 : entity work.and2(simple) generic map ( Tpd => 2 ns ) port map ( a => sig1, b => sig2, y => sig_out ); gate2 : entity work.and2(simple) generic map ( Tpd => 3 ns ) port map ( a => a1, b => b1, y => sig1 ); -- Example 12.1, Page 367 entity control_unit is generic ( Tpd_clk_out, Tpw_clk : delay_length; debug : boolean := false ); port ( clk : in bit; ready : in bit; control1, control2 : out bit ); end entity control_unit; -- Page 368 generic map ( 200 ps, 1500 ps, false ) generic map ( Tpd_clk_out => 200 ps, Tpw_clk => 1500 ps ) generic map ( 200 ps, 1500 ps, debug => open ) -- Example 12.2, Page 368 entity D_flipflop is generic ( Tpd_clk_q, Tsu_d_clk, Th_d_clk : delay_length ); port ( clk, d : in bit; q : out bit ); end entity D_flipflop; architecture basic of D_flipflop is begin behavior : q <= d after Tpd_clk_q when rising_edge(clk); check_setup : process is begin wait until clk; assert d'last_event >= Tsu_d_clk report "setup violation"; end process check_setup; check_hold : process is begin wait until clk'delayed(Th_d_clk); assert d'delayed'last_event >= Th_d_clk report "hold violation"; end process check_hold; end architecture basic; request_flipflop : entity work.D_flipflop(basic) generic map ( Tpd_clk_q => 4 ns, Tsu_d_clk => 3 ns, Th_d_clk => 1 ns ) port map ( clk => system_clock, d => request, q => request_pending ); -- Page 369 entity reg is port ( d : in bit_vector; q : out bit_vector; ... ); end entity reg; signal small_data : bit_vector(0 to 7); signal large_data : bit_vector(0 to 15); ... problem_reg : entity work.reg port map ( d => small_data, q => large_data, ... ); entity reg is generic ( width : positive ); port ( d : in bit_vector(0 to width - 1); q : out bit_vector(0 to width - 1); ... ); end entity reg; signal in_data, out_data : bit_vector(0 to bus_size - 1); ... ok_reg : entity work.reg generic map ( width => bus_size ) port map ( d => in_data, q => out_data, ... ); -- Example 12.3, Page 370 entity reg is generic ( width : positive ); port ( d : in bit_vector(0 to width - 1); q : out bit_vector(0 to width - 1); clk, reset : in bit ); end entity reg; -------------------------------------------------- architecture behavioral of reg is begin behavior : process (clk, reset) is constant zero : bit_vector(0 to width - 1) := (others => '0'); begin if reset then q <= zero; elsif rising_edge(clk) then q <= d; end if; end process behavior; end architecture behavioral; word_reg : entity work.reg(behavioral) generic map ( width => 32 ) port map ( ... ); subtype state_vector is bit_vector(1 to 5); ... -- Example 12.3, Page 371 state_reg : entity work.reg(behavioral) generic map ( width => state_vector'length ) port map ( ... ); -- Example 12.4, Page 371 entity adder is generic ( width : positive; Tpd_ab_s : time_vector(width - 1 downto 0) ); port ( a, b : in bit_vector(width - 1 downto 0); c_in : in bit; s : out bit_vector(width - 1 downto 0); c_out : out bit ); end entity adder; subtype byte is bit_vector(7 downto 0); signal op1, op2, result : byte; signal c_out : bit; ... byte_adder : entity work.adder generic map ( width => byte'length, Tpd_ab_s => (7 downto 1 => 120 ps, 0 => 80 ps) ) port map ( a => op1, b => op2, c_in => '0', s => result, c_out => c_out ); generic map ( Tpd_ab_s => (7 downto 1 => 120 ps, 0 => 80 ps), width => byte'length ) ---------------------------------------------------------------- -- 12.2 Generic Types ---------------------------------------------------------------- -- Example 12.5, Page 372 entity generic_mux2 is generic ( type data_type ); port ( sel : in bit; a, b : in data_type; z : out data_type ); end entity generic_mux2; -- Example 12.5, Page 373 architecture rtl of mux2 is begin z <= a when not sel else b; end architecture rtl; signal sel_bit, a_bit, b_bit, z_bit : bit; ... bit_mux : entity work.generic_mux2(rtl) generic map ( data_type => bit ) port map ( sel => sel_bit, a => a_bit, b => b_bit, z => z_bit ); type msg_packet is record src, dst : unsigned(7 downto 0); pkt_type : bit_vector(2 downto 0); length : unsigned(4 downto 0); payload : byte_vector(0 to 31); checksum : unsigned(7 downto 0); end record msg_packet; signal pkt_sel : bit; signal pkt_in1, pkt_in2, pkt_out : msg_pkt; ... pkt_mux : entity work.generic_mux2(rtl) generic map ( data_type => msg_packet ) port map ( sel => pkt_sel, a => pkt_in1, b => pkt_in2, z => pkt_out ); -- Page 374 signal s1, s2 : T; ... s1 <= s2 after 10 ns; variable v1, v2, temp : T; ... temp := v1; v1 := v2; v2 := temp; entity e is generic ( type T; constant init_val : T ); port ( ... ); end entity e; architecture a of e is begin p : process is variable v : T := init_val; begin ... end process p; end architecture a; my_e : entity work.e(a) generic map ( T => std_ulogic_vector(3 downto 0), init_val => "ZZZZ" ); -- Example 12.6, Page 375 entity generic_counter is generic ( type count_type; constant reset_value : count_type ); port ( clk, reset : in bit; data : out count_type ); end entity generic_counter; architecture rtl of generic_counter is begin count : process (clk) is begin if rising_edge(clk) then if reset then data <= reset_value; else data <= data + 1; -- Illegal end if; end if; end process count; end architecture rtl; type traffic_light_color is (red, yellow, green); ... cycle_lights : entity work.generic_counter(rtl) generic map ( count_type => traffic_light_color, reset_value => red ) port map ( ... ); ---------------------------------------------------------------- -- 12.3 Generic Lists in Packages ---------------------------------------------------------------- -- Example 12.7, Page 377 package generic_stacks is generic ( size : positive; type element_type ); type stack_array is array (0 to size-1) of element_type; type stack_type is record SP : integer range 0 to size-1; store : stack_array; end record stack_type; procedure push (s : inout stack_type; e : in element_type); procedure pop (s : inout stack_type; e : out element_type); end package generic_stacks; package body generic_stacks is procedure push (s : inout stack_type; e : in element_type) is begin s.store(s.SP) := e; s.SP := (s.SP + 1) mod size; end procedure push; procedure pop (s : inout stack_type; e : out element_type) is begin s.SP := (s.SP - 1) mod size; e := s.store(s.SP); end procedure pop; end package body generic_stacks; -- Example 12.7, Page 378 use work.generic_stacks.all; -- Illegal ... variable my_stack : work.generic_stacks.stack_type; -- Illegal library ieee; use ieee.numeric_std.all; package address_stacks is new work.generic_stacks generic map ( size => 8, element_type => unsigned(23 downto 0) ); architecture behavior of CPU is use work.address_stacks.all; ... begin interpret_instructions : process is variable return_address_stack : stack_type; variable PC : unsigned(23 downto 0); ... begin ... case opcode is when jsb => push(return_address_stack, PC); PC <= jump_target; when ret => pop(return_address_stack, PC); ... end case; ... end process interpret_instructions; end architecture behavior; -- Page 379 package address_stacks is new work.generic_stacks generic map ( size => 8, element_type => unsigned(23 downto 0) ); package operand_stacks is new work.generic_stacks generic map ( size => 16, element_type => real ); use work.address_stacks.all, work.operand_stacks.all; use work.address_stacks, work.operand_stacks; variable return_address_stack : address_stacks.stack; variable PC : unsigned(23 downto 0); variable FP_operand_stack : operand_stacks.stack; variable TOS_operand : real; ... address_stacks.push(return_address_stack, PC); operand_stacks.pop(FP_operand_stack, TOS_operand); -- Page 380 type T1 is array (1 to 10) of integer; type T2 is array (1 to 10) of integer; package generic_pkg is generic ( type T1; type T2 ); procedure proc ( x : T1 ); procedure proc ( x : T2 ); procedure proc ( x : bit ); end package generic_pkg; package integer_boolean_pkg is new work.generic_pkg generic map ( T1 => integer, T2 => boolean ); work.integer_boolean_pkg.proc(3); work.integer_boolean_pkg.proc(false); work.integer_boolean_pkg.proc('1'); package integer_bit_pkg is new work.generic_pkg generic map ( T1 => integer, T2 => bit ); work.integer_bit_pkg.proc('1'); -- Page 381 package integer_integer_pkg is new work.generic_pkg generic map ( T1 => integer, T2 => integer ); work.integer_integer_pkg.proc(3); ---------------------------------------------------------------- -- 12.3.1 Local Packages ---------------------------------------------------------------- -- Example 12.8, Page 382 stim_gen : process is package ID_manager is package ID_wrappers is generic ( type test_case_type ); type wrapped_test_case is record test_case : test_case_type; ID : natural; end record wrapped_test_case; impure function wrap_test_case ( test_case : test_case_type ) return wrapped_test_case; end package ID_wrappers; end package ID_manager; package body ID_manager is variable next_ID : natural := 0; package body ID_wrappers is impure function wrap_test_case ( test_case : test_case_type ) return wrapped_test_case is variable result : wrapped_test_case; begin result.test_case := test_case; result.ID := next_ID; next_ID := next_ID + 1; return result; end function wrap_test_case; end package body ID_wrappers; end package body ID_manager; use ID_manager.ID_wrappers; package word_wrappers is new ID_wrappers generic map ( test_case_type => unsigned(32 downto 0) ); package real_wrappers is new ID_wrappers generic map ( test_case_type => real ); variable next_word_test : word_wrappers.wrapped_test_case; variable next_real_test : real_wrappers.wrapped_test_case; begin ... next_word_test := word_wrappers.wrap_test_case(X"0440CF00"); next_real_test := real_wrappers.wrap_test_case(3.14159); ... end process stim_gen; -- Example 12.9, Page 384 subprogram analyze_network ( network : network_type ) is type vertex_type is ...; type edge_type is ...; constant max_diameter : positive := 30; package vertex_stacks is new work.generic_stacks generic map ( size => max_diameter, element_type => vertex_type ); use vertext_stacks.all; variable current_vertex : vertex_type; variable pending_vertices : stack_type; begin ... push(pending_stacks, current_vertex); ... end subprogram analyze_network; ---------------------------------------------------------------- -- 12.3.2 Abstract Data Types Using Packages ---------------------------------------------------------------- -- Example 12.10, Page 385 package bounded_buffer_adt is generic ( size : positive; type element_type ); type store_array is array (0 to size - 1) of element_type; type bounded_buffer is record count : natural; head, tail : natural; store : store_array; end record bounded_buffer; procedure reset ( b : inout bounded_buffer ); -- resets a bounded buffer to be empty function is_empty ( b : bounded_buffer ) return boolean; -- tests whether the bounded buffer is empty -- (i.e., no data to read) function is_full ( b : bounded_buffer ) return boolean; -- tests whether the bounded buffer is full --(i.e., no data can be written) procedure write ( b : inout bounded_buffer; data : in element_type ); -- if the bounded buffer is not full, writes the data -- if it is full, assertion violation with severity failure procedure read ( b : inout bounded_buffer; data : out element_type ); -- if the bounded buffer is not empty, read the first item -- if it is empty, assertion violation with severity failure end package bounded_buffer_adt; -- Example 12.10, Page 386 receiver : process is subtype byte is bit_vector(0 to 7); package byte_buffer_adt is new work.bounded_buffer_adt generic map ( size => 2048, element_type => byte ); use work.byte_buffer_adt.all; variable receive_buffer : bounded_buffer; ... begin reset(receive_buffer); ... if is_full(receive_buffer) then ... -- buffer overrun else write(receive_buffer, received_byte); end if; ... if is_empty(receive_buffer) then ... -- buffer underrun else read(receive_buffer, check_byte); end if; ... end process receiver; -- Example 12.10, Page 388 package body bounded_buffer_adt is procedure reset ( b : inout bounded_buffer ) is begin b.count := 0; b.head := 0; b.tail := 0; end procedure reset; function is_empty ( b : bounded_buffer ) return boolean is begin return b.count = 0; end function is_empty; function is_full ( b : bounded_buffer ) return boolean; begin return b.count = size; end function is_full; procedure write ( b : inout bounded_buffer; data : in element_type ) is begin if is_full(b) then report "write to full bounded buffer" severity failure; else b.store(b.tail) := data; b.tail := (b.tail + 1) mod size; b.count := b.count + 1; end if; end procedure write; procedure read ( b : inout bounded_buffer; data : out element_type ) is begin if is_empty(b) then report "read from empty bounded buffer" severity failure; else data := b.store(b.head); b.head := (b.head + 1) mod size; b.count := b.count - 1; end if; end procedure read; end package body bounded_buffer_adt; ---------------------------------------------------------------- -- 12.4 Generic Lists in Subprograms ---------------------------------------------------------------- -- Example 12.11, Page 390 procedure swap generic ( type T ) parameter ( a, b : inout T ) is variable temp : T; begin temp := a; a := b; b := temp; end procedure swap; -- Example 12.11, Page 391 procedure int_swap is new swap generic map ( T => integer ); procedure vec_swap is new swap generic map ( T => bit_vector(0 to 7) ); variable a_int, b_int : integer; variable a_vec, b_vec : bit_vector(0 to 7); ... int_swap(a_int, b_int); vec_swap(a_vec, b_vec); swap(a_int, b_int); -- Illegal procedure string_swap is new swap generic map ( T => string ); -- Example 12.12, Page 391 package timing_pkg is procedure check_setup generic ( type signal_type; type clk_type; clk_active_value : clk_type; T_su : delay_length ) ( signal s : signal_type; signal clk : clk_type ); ... end package timing_pkg; package body timing_pkg is procedure check_setup generic ( type signal_type; type clk_type; clk_active_value : clk_type; T_su : delay_length ) ( signal s : signal_type; signal clk : clk_type ) is begin if clk'event and clk = clk_active_value then assert s'last_event >= T_su report "Setup time violation" severity error; end if; end procedure check_setup; ... end package body timing_pkg; -- Example 12.12, Page 392 use work.timing_pkg.all; procedure check_normal_setup is new check_setup generic map ( signal_type => std_ulogic, clk_type => std_ulogic, clk_active_value => '1', T_su => 200ps ); procedure check_normal_setup is new check_setup generic map ( signal_type => std_ulogic_vector, clk_type => std_ulogic, clk_active_value => '1', T_su => 200ps ); procedure check_long_setup is new check_setup generic map ( signal_type => std_ulogic_vector, clk_type => std_ulogic, clk_active_value => '1', T_su => 300ps ); signal status : std_ulogic; signal data_in, result : std_ulogic_vector(23 downto 0); ... check_normal_setup(status, clk); check_normal_setup(result, clk); check_long_setup(data_in, clk); ... -- Page 393 procedure combine generic ( type T ) parameter ( x : T; value : bit ); procedure combine generic ( type T ) parameter ( x : T; value : integer ); procedure combine_vec_with_bit is new combine[T, bit] generic map ( T => bit_vector ); ---------------------------------------------------------------- -- 12.5 Generic Subprograms ---------------------------------------------------------------- -- Example 12.13, Page 395 entity generic_counter is generic ( type count_type; constant reset_value : count_type; function increment ( x : count_type ) return count_type ); port ( clk, reset : in bit; data : out count_type ); end entity generic_counter; architecture rtl of generic_counter is begin count : process (clk) is begin if rising_edge(clk) then if reset then data <= reset_value; else data <= increment(data); end if; end if; end process count; end architecture rtl; use ieee.numeric_std.all; function add1 ( arg : unsigned ) return unsigned is begin return arg + 1; end function add1; signal clk, reset : bit; signal count_val : unsigned(15 downto 0); ... counter : entity work.generic_counter(rtl) generic map ( count_type => unsigned(15 downto 0), reset_value => (others => '0'), increment => add1 ) -- add1 is the -- actual function port map ( clk => clk, reset => reset, data => count_val ); -- Example 12.13, Page 396 type traffic_light_color is (red, yellow, green); function next_color ( arg : traffic_light_color ) return traffic_light_color is begin if arg = traffic_light_color'high then return traffic_light_color'low; else return traffic_light_color'succ(arg); end if; end function next_color; signal east_light : traffic_light_color; ... east_counter : work.generic_counter(rtl) generic map ( count_type => traffic_light_color, reset_value => red, increment => next_color ) -- next_color is the -- actual function port map ( clk => clk, reset => reset, data => east_light ); -- Example 12.14, Page 397 package error_utility_pkg is procedure report_error ( report_string : string; report_severity : severity_level ); end package error_utility_pkg; package body error_utility_pkg is procedure report_error ( report_string : string; report_severity : severity_level ) is begin report report_string severity report_severity; end procedure report_error; end package body error_utility_pkg; package operations is generic ( procedure error_action ( report_string : string; report_severity : severity_level ) is work.error_utility_pkg.report_error ); procedure step1 ( ... ); ... end package operations; package body operations is procedure step1 ( ... ) is begin ... if something_is_wrong then error_action("Something is wrong in step1", error); end if; ... end procedure step1; ... end package body operations; -- Example 12.14, Page 398 package reporting_operations is new work.operations; use reporting_operations.all; ... step1 ( ... ); constant stop_status : integer := -1; procedure stop_on_error ( report_string : string; report_severity : severity_level ) is begin report report_string severity report_severity; std.env.stop(stop_status); end procedure stop_on_error; -- Example 12.14, Page 399 package debugging_operations is new work.operations generic map ( error_action => stop_on_error ); use debugging_operations.all; ... step1 ( ... ); -- Page 399 function minimum ( L, R : T ) return T is <> -- Example 12.15, Page 399 entity generic_counter is generic ( type count_type; constant reset_value : count_type; function "+" ( L : count_type; R : natural ) return count_type is <> ); port ( clk, reset : in bit; data : out count_type ); end entity generic_counter; -- Example 12.15, Page 400 architecture rtl of generic_counter is begin count : process (clk) is begin if rising_edge(clk) then if reset then data <= reset_value; else data <= data + 1; end if; end if; end process count; end architecture rtl; use ieee.numeric_std.all; signal clk, reset : bit; signal count_val : unsigned(15 downto 0); ... counter : entity work.generic_counter(rtl) generic map ( count_type => unsigned(15 downto 0), reset_value => (others => '0') ) port map ( clk => clk, reset => reset, data => count_val ); -- Example 12.16, Page 401 package dictionaries is generic ( size : positive; type element_type; type key_type; function key_of ( E : element_type ) return key_type; function "<" ( L, R : key_type ) return boolean is <> ); type element_array is array (1 to size) of element_type; type dictionary_type is record store : element_array; count : natural; end record dictionary_type; procedure initialize ( dictionary : inout dictionary_type ); procedure lookup ( dictionary : in dictionary_type; lookup_key : in key_type; element : out element_type; found : out boolean ); procedure search_and_insert ( dictionary : in dictionary_type; element : in element_type; already_present : out boolean ); end package dictionaries; package body dictionaries is procedure initialize ( dictionary : inout dictionary_type ) is begin dictionary.count := 0; end procedure initialize; procedure lookup ( dictionary : in dictionary_type; lookup_key : in key_type; element : out element_type; found : out boolean ) is variable left, right, middle : natural; begin found := false; left := 1; right := dictionary.count; while left <= right loop middle := (left + right) / 2; if lookup_key < key_of( dictionary.store(middle) ) then right := middle - 1; elsif key_of( dictionary.store(middle) ) < lookup_key then left := middle + 1; else found := true; element := dictionary.store(middle); return; end if; end loop; end procedure lookup; procedure search_and_insert ( dictionary : inout dictionary_type; element : in element_type; already_present : out boolean ) is ... end package body dictionaries; -- Example 12.16, Page 402 type test_pattern_type is ...; function test_time_of ( test_pattern : in test_pattern_type ) return time is begin return ...; end function test_time_of; package test_pattern_dictionaries is new work.dictionaries generic map ( size => 1000, element_type => test_pattern_type, key_type => time, key_of => test_time_of ); -- Example 12.16, Page 403 use test_pattern_dictionaries.all; variable test_set : dictionary_type; variable generated_test, sought_test : test_pattern_type; variable was_present : boolean; ... initialize ( test_set ); ... search_and_insert ( test_set, generated_test, was_present ); assert not was_present report "Test at " & to_string(test_time_of(generated_test)) & " previously generated"; ... lookup ( test_set, 10 ns, sought_test, was_present ); assert was_present report "Test at 10 ns not found in test set"; -- Example 12.17, Page 403 package dictionaries is generic ( ... ); ... procedure traverse generic ( procedure action ( element : in element_type ) ) parameter ( dictionary : in dictionary_type ); end package dictionaries; package body dictionaries is ... procedure traverse generic ( procedure action ( element : in element_type ) ) parameter ( dictionary : in dictionary_type ) is begin for i in 1 to dictionary.count loop action ( dictionary.store(i) ); end loop; end procedure traverse; end package body dictionaries; -- Example 12.17, Page 404 variable previous_time : time := time'low; variable smallest_so_far : time := time'high; procedure compare_test_pattern ( test_pattern : in test_pattern_type ) is begin smallest_so_far := minimum(smallest_so_far, test_time_of(test_pattern) - previous_time ); previous_time := test_time_of(test_pattern); end procedure count_a_test_pattern; procedure find_smallest_interval is new traverse generic map ( action => compare_test_pattern ); find_smallest_interval(test_set); report "The smallest interval between test patterns is " & to_string(smallest_so_far); procedure display_test_pattern ( test_pattern : in test_pattern_type ) is begin report "Test at " & to_string(test_time_of(test_pattern)) & LF & ...; end procedure display_test_pattern; procedure display_all_test_patterns is new traverse generic map ( action => display_test_pattern ); display_all_test_patterns(test_set); -- Page 405 entity up_down_counter is generic ( type T; function add ( x : T; by : integer := 1 ) return T ) port ( ... ); end entity up_down_counter; architecture rtl of up_down_counter is begin count : process (clk) is begin if rising_edge(clk) then if mode then count_value <= add(count_value); -- use default value else count_value <= add(count_value, -1); end if; end if; end process count; end architecture rtl; -- Page 406 function add_int ( a : integer; incr : integer := 0 ) return integer is begin return a + incr; end function add_int; ... int_counter : entity work.up_down_counter(rtl) generic map ( T => integer; add => add_int ) port map ( ... ); function add ( x : T; by : integer ) return T function add_nat ( a : natural; incr : natural := 0 ) return natural is begin return a + incr; end function add_nat; ... nat_counter : entity work.up_down_counter(rtl) generic map ( T => natural; add => add_nat ) port map ( ... ); ---------------------------------------------------------------- -- 12.6 Generic Packages ---------------------------------------------------------------- -- Example 12.18, Page 407 library ieee; use ...; package fixed_generic_pkg is generic ( fixed_round_style : fixed_round_style_type := fixed_round; fixed_overflow_style : fixed_overflow_style_type := fixed_saturate; fixed_guard_bits : natural := 3; no_warning : boolean := false ); ... end package fixed_generic_pkg; -- Example 12.18, Page 408 library ieee; package complex_generic_pkg is generic ( left, right : integer; package fixed_pkg_for_complex is new ieee.fixed_generic_pkg generic map (<>) ); use fixed_pkg_for_complex.all; type complex is record re, im : sfixed(left downto right); end record; function "-" ( z : complex ) return complex; function conj ( z : complex ) return complex; function "+" ( l : complex; r : complex ) return complex; function "-" ( l : complex; r : complex ) return complex; function "*" ( l : complex; r : complex ) return complex; function "/" ( l : complex; r : complex ) return complex; end package complex_generic_pkg; -- Example 12.18, Page 409 package body fixed_complex_pkg is function "-" ( z : complex ) return complex is begin return ( -z.re, -z.im ); end function "-"; ... end package body fixed_complex_pkg; package dsp_fixed_pkg is new ieee.fixed_generic_pkg generic map ( fixed_rounding_style => fixed_round, fixed_overflow_style => fixed_saturate, fixed_guard_bits => 2, no_warning => false ); package dsp_complex_pkg is new work.complex_generic_pkg generic map ( left => 3, right => -12, fixed_pkg_for_complex => dsp_fixed_pkg ); use dsp_fixed_pkg.all, dsp_complex_pkg.all; variable a, b, z : complex variable c : sfixed; ... z := a + conj(b); z := (c * z.re, c * z.im); -- Example 12.19, Page 410 package fixed_math_ops is generic ( package fixed_pkg_for_math is new ieee.fixed_generic_pkg generic map (<>) ); use fixed_pkg_for_math.all; function sqrt ( x : sfixed ) return sfixed; function exp ( x : sfixed ) return sfixed; ... end package fixed_math_ops; -- Example 12.19, Page 411 package complex_math_ops is generic ( left, right : integer; package fixed_pkg_for_complex_math is new ieee.fixed_generic_pkg generic map (<>); package fixed_math_ops is new work.fixed_math_ops generic map ( fixed_pkg_for_math => fixed_pkg_for_complex_math ); package complex_pkg is new work.complex_generic_pkg generic map ( left => left, right => right, fixed_pkg_for_complex => fixed_pkg_for_complex_math ) ); use fixed_pkg_for_complex_math.all, fixed_math_ops.all, complex_pkg.all; function "abs" ( z : complex ) return sfixed; function arg ( z : complex ) return sfixed; function sqrt ( z : complex ) return complex; ... end package complex_math_ops; package body complex_math_ops is function "abs" ( z : complex ) return sfixed is begin return sqrt(z.re * z.re + z.im * z.im); end function "abs"; ... end package body complex_math_ops; -- Example 12.19, Page 412 package dsp_fixed_math_ops is new work.fixed_math_ops generic map ( fixed_pkg_for_math => dsp_fixed_pkg ); package dsp_complex_math_ops is new work.complex_math_ops generic map ( left => 3, right => -12, fixed_pkg_for_complex_math => dsp_fixed_pkg, fixed_math_ops => dsp_fixed_math_ops, complex_pkg => dsp_complex_pkg ); -- Page 413 package pkg1 is generic ( function "<" ( L, R : integer ) return boolean is <> ) ); ... end package pkg1; package pkg2 is generic ( package inst1 is new pkg1 generic map ( default ) ); ... end package pkg2; package ascending_pkg1 is new pkg1 generic map ( T => integer ); package integer_pkg2 is new pkg2 generic map ( inst1 => ascending_pkg1 ); ---------------------------------------------------------------- -- Exercises ---------------------------------------------------------------- -- Exercise 1 entity flipflop is port ( clk, d : in bit; q, q_n : out bit ); end entity flipflop; -- Exercise 2 entity clock_generator is generic ( period : delay_length ); port ( clk : out std_ulogic ); end entity clock_generator; -- Exercise 3 entity adder is generic ( data_length : positive ); port ( a, b : in ...; sum : out ... ); end entity adder; -- Exercise 4 signal data_out : bit_vector(7 downto 0); -- Exercise 6 my_e : entity work.e(a) generic map ( T => unsigned, init_val => unsigned'("00000000") ) port map ( ... ); -- Exercise 8 package int_std_pkg is new generic_pkg generic map ( T1 => integer, T2 => std_ulogic ); variable b : bit; ... int_std_pkg(1); int_std_pkg('1'); int_std_pkg(b);