---------------------------------------------------------------- -- Chapter 7 Packages and Use Clauses ---------------------------------------------------------------- ---------------------------------------------------------------- -- 7.1 Package Declarations ---------------------------------------------------------------- -- Example 7.1, Page 246 package cpu_types is constant word_size : positive := 16; constant address_size : positive := 24; subtype word is bit_vector(word_size - 1 downto 0); subtype address is bit_vector(address_size - 1 downto 0); type status_value is ( halted, idle, fetch, mem_read, mem_write, io_read, io_write, int_ack ); end package cpu_types; -- Page 246 work.cpu_types.status_value -- Example 7.2, Page 246 entity address_decoder is port ( addr : in work.cpu_types.address; status : in work.cpu_types.status_value; mem_sel, int_sel, io_sel : out bit ); end entity address_decoder; -------------------------------------------------- architecture functional of address_decoder is constant mem_low : work.cpu_types.address := X"000000"; constant mem_high : work.cpu_types.address := X"EFFFFF"; constant io_low : work.cpu_types.address := X"F00000"; constant io_high : work.cpu_types.address := X"FFFFFF"; begin mem_decoder : mem_sel <= '1' when ( work.cpu_types."=" (status, work.cpu_types.fetch) or work.cpu_types."="( status, work.cpu_types.mem_read) or work.cpu_types."=" (status, work.cpu_types.mem_write) ) and addr >= mem_low and addr <= mem_high else '0'; int_decoder : int_sel <= '1' when work.cpu_types."=" (status, work.cpu_types.int_ack) else '0'; io_decoder : io_sel <= '1' when ( work.cpu_types."=" (status, work.cpu_types.io_read) or work.cpu_types."=" (status, work.cpu_types.io_write) ) and addr >= io_low and addr <= io_high else '0'; end architecture functional; -- Example 7.2, Page 247 work.cpu_types.status_value'(work.cpu_types.fetch) -- Page 248 variable stored_state : ieee.std_logic_1164.std_ulogic; -- Example 7.3, Page 248 library ieee; use ieee.std_logic_1164.all; package clock_pkg is constant Tpw : delay_length := 4 ns; signal clock_phase1, clock_phase2 : std_ulogic; end package clock_pkg; library ieee; use ieee.std_logic_1164.all; entity io_controller is port ( ref_clock : in std_ulogic; ... ); end entity io_controller; -------------------------------------------------- architecture top_level of io_controller is ... begin internal_clock_gen : entity work.phase_locked_clock_gen(std_cell) port map ( reference => ref_clock, phi1 => work.clock_pkg.clock_phase1, phi2 => work.clock_pkg.clock_phase2 ); the_bus_sequencer : entity work.bus_sequencer(fsm) port map ( rd, wr, sel, width, burst, addr(1 downto 0), ready, control_reg_wr, status_reg_rd, data_fifo_wr, data_fifo_rd, ... ); ... end architecture top_level; -- Example 7.3, Page 249 architecture fsm of bus_sequencer is -- This architecture implements the sequencer as -- a finite-state machine. NOTE: it uses the clock signals -- from clock_pkg to synchronize the fsm. signal next_state_vector : ...; begin bus_sequencer_state_register : entity work.state_register(std_cell) port map ( phi1 => work.clock_pkg.clock_phase1, phi2 => work.clock_pkg.clock_phase2, next_state => next_state_vector, ... ); ... end architecture fsm; ---------------------------------------------------------------- -- 7.1.1 Subprograms in Package Declarations ---------------------------------------------------------------- -- Page 250 subtype word32 is bit_vector(31 downto 0); procedure add ( a, b : in word32; result : out word32; overflow : out boolean ); function "<" ( a, b : in word32 ) return boolean; ---------------------------------------------------------------- -- 7.1.2 Constants in Package Declarations ---------------------------------------------------------------- -- Page 251 constant max_buffer_size : positive; constant max_buffer_size : positive := 4096; -- Example 7.4, Page 251 package cpu_types is constant word_size : positive := 16; constant address_size : positive := 24; subtype word is bit_vector(word_size - 1 downto 0); subtype address is bit_vector(address_size - 1 downto 0); type status_value is ( halted, idle, fetch, mem_read, mem_write, io_read, io_write, int_ack ); subtype opcode is bit_vector(5 downto 0); function extract_opcode ( instr_word : word ) return opcode; constant op_nop : opcode := "000000"; constant op_breq : opcode := "000001"; constant op_brne : opcode := "000010"; constant op_add : opcode := "000011"; ... end package cpu_types; architecture behavioral of cpu is begin interpreter : process is variable instr_reg : work.cpu_types.word; variable instr_opcode : work.cpu_types.opcode; begin ... -- initialize loop ... -- fetch instruction instr_opcode := work.cpu_types.extract_opcode(instr_reg); case instr_opcode is when work.cpu_types.op_nop => null; when work.cpu_types.op_breq => ... ... end case; end loop; end process interpreter; end architecture behavioral; ---------------------------------------------------------------- -- 7.2 Package Bodies ---------------------------------------------------------------- -- Example 7.5, Page 253 package bit_vector_signed_arithmetic is function "+" ( bv1, bv2 : bit_vector ) return bit_vector; function "-" ( bv : bit_vector ) return bit_vector; function "*" ( bv1, bv2 : bit_vector ) return bit_vector; ... end package bit_vector_signed_arithmetic; package body bit_vector_signed_arithmetic is function "+" ( bv1, bv2 : bit_vector ) return bit_vector is ... function "-" ( bv : bit_vector ) return bit_vector is ... function mult_unsigned ( bv1, bv2 : bit_vector ) return bit_vector is ... begin ... end function mult_unsigned; function "*" ( bv1, bv2 : bit_vector ) return bit_vector is begin if not bv1(bv1'left) and not bv2(bv2'left) then return mult_unsigned(bv1, bv2); elsif not bv1(bv1'left) and bv2(bv2'left) then return -mult_unsigned(bv1, -bv2); elsif bv1(bv1'left) and not bv2(bv2'left) then return -mult_unsigned(-bv1, bv2); else return mult_unsigned(-bv1, -bv2); end if; end function "*"; ... end package body bit_vector_signed_arithmetic; ---------------------------------------------------------------- -- 7.2.1 Local Packages ---------------------------------------------------------------- -- Example 7.6, Page 255 stim_gen : process is package ID_manager is impure function get_ID return natural; end package ID_manager; package body ID_manager is variable next_ID : natural := 0; impure function get_ID return natural is variable result : natural; begin result := next_ID; next_ID := next_ID + 1; return result; end function get_ID; end package body ID_manager; ... type test_case is record ... ID : natural; end record test_case; variable next_test_case : test_case; begin ... next_test_case.ID := ID_manager.get_ID; ID_manager.next_ID := 0; -- Illegal ... end process stim_gen; -- Page 256 package outer is ... package inner is impure function f ( ... ) return natural; end package inner; ... end package outer; package body outer is ... package body inner is ... impure function f ( ... ) return natural is ... end function f; end package body inner; ... end package body outer; -- Page 257 package outer is ... end package outer; package body outer is ... package inner is ... end package inner; package body inner is ... end package body inner; ... end package body outer; ---------------------------------------------------------------- -- 7.3 Use Clauses ---------------------------------------------------------------- -- Page 258 use work.cpu_types; variable data_word : cpu_types.word; variable next_address : cpu_types.address; use work.cpu_types.word, work.cpu_types.address; variable data_word : word; variable next_address : address; use ieee.std_logic_1164.all; -- Page 259 use ID_manager.all; next_test_case.ID := get_ID; -- Example 7.7, Page 259 architecture behavioral of cpu is begin interpreter : process is use work.cpu_types.all; variable instr_reg : word; variable instr_opcode : opcode; begin ... -- initialize loop ... -- fetch instruction instr_opcode := extract_opcode ( instr_reg ); case instr_opcode is when op_nop => null; when op_breq => ... ... end case; end loop; end process interpreter; end architecture behavioral; -- Page 260 package stuff_pkg is type color_type is (red, orange, yellow, green, blue, violet); subtype warm_color is color_type range red to yellow; function "<" ( c1, c2 : color_type ) return boolean; function pretty ( c : color_type ) return boolean; type resistance is range 0 to 1E9 units Ohm; kOhm = 1000 Ohm; MOhm = 1000 kOhm; end units; subtype weak_logic is IEEE.std_logic_1164.std_ulogic range 'W' to 'H'; end package stuff_pkg; use stuff_pkg.color_type; use stuff_pkg.warm_color; -- Page 261 use stuff_pkg.resistance; use stuff_pkg.weak_logic; ---------------------------------------------------------------- -- 7.3.1 Visibility of Used Declarations ---------------------------------------------------------------- -- Page 261 library ieee; use ieee.std_logic_1164.std_ulogic; entity logic_block is port ( a, b : in std_ulogic; y, z : out std_ulogic ); end entity logic_block; -- Page 262 use work.cpu_types.all; architecture behavior of cpu is signal address : bit_vector(15 downto 0); ... end architecture behavior; package short_int_types is type short_int is range 0 to 255; end package short_int_types use work.short_int_types.all; package short_int_ops is function "+" ( L, R : short_int ) return short_int; constant maximum : short_int := 255; ... end package short_int_ops; -- Page 263 use work.short_int_types.all, work.short_int_ops.all; architecture behavior of alu is ... end architecture behavior; package controller_types is subtype address is bit_vector(2 downto 0); constant int_ack : address := "100"; end package controller_types; use work.cpu_types.all, work.controller_types.all; architecture rtl of system is ... end architecture rtl; package int_ops is function increment ( a : inout integer; n : in integer := 1 ); end package int_ops; package counter_ops is function increment ( c : inout integer; n : in integer := 1 ); end package counter_ops; use work.int_ops.all, work.counter_ops.all; -- Page 264 increment ( a => count_value, n => -1 ); increment ( c => count_value, n => -1 ); ---------------------------------------------------------------- -- Exercises ---------------------------------------------------------------- -- Exercise 9 package identifier_pkg is subtype identifier is string(1 to 15); constant max_table_size : integer := 50; subtype table_index is integer range 1 to max_table_size; type table is array (table_index) of identifier; ... end package identifier_pkg;