---------------------------------------------------------------- -- Chapter 23 Miscellaneous Topics ---------------------------------------------------------------- ---------------------------------------------------------------- -- 23.1 Guards and Blocks ---------------------------------------------------------------- ---------------------------------------------------------------- -- 23.1.1 Guarded Signals and Disconnection ---------------------------------------------------------------- -- Page 734 signal interrupt_request : pulled_up bit bus; signal stored_state : resolve_state state_type register := init_state; -- Example 23.1, Page 735 architecture top_level of computer_system is function resolve_bits ( bits : bit_vector ) return bit is variable result : bit := '0'; begin for index in bits'range loop result := result or bits(index); exit when result; end loop; return result; end function resolve_bits; signal write_en : resolve_bits bit bus; ... begin CPU : process is ... begin write_en <= '0' after Tpd; ... loop wait until clock; if hold_req then write_en <= null after Tpd; wait on clock until clock and not hold_req; write_en <= '0' after Tpd; end if; ... end loop; end process CPU; ... end architecture top_level; -- Example 23.2, Page 736 architecture rtl of processor is subtype word is bit_vector(0 to 31); type word_vector is array (natural range <>) of word; function resolve_unique ( drivers : word_vector ) return word is begin return drivers(drivers'left); end function resolve_unique; signal source1, source2 : resolve_unique word register; ... begin source1_reg : process (phase1, source1_reg_out_en, ...) is variable stored_value : word; begin ... if source1_reg_out_en and phase1 then source1 <= stored_value; else source1 <= null; end if; end process source1_reg; alu : perform_alu_op ( alu_opcode, source1, source2, destination, ... ); ... end architecture rtl; -- Page 737 subtype word is bit_vector(0 to 31); type word_array is array (integer range <>) of word; function resolve_words ( words : word_array ) return word; signal s : resolve_words word bus; s(0 to 15) <= X"003F" after T_delay; s(16 to 31) <= null after T_delay; ---------------------------------------------------------------- -- The Driving Attribute ---------------------------------------------------------------- ---------------------------------------------------------------- -- Guarded Ports ---------------------------------------------------------------- -- Page 738 subtype byte is bit_vector(0 to 7); type byte_array is array (integer range <>) of byte; function resolve ( bytes : byte_array ) return byte; subtype resolved_byte is resolve byte; entity tri_state_reg is port ( d : in resolved_byte; q : out resolved_byte bus; clock, out_enable : in bit ); end entity tri_state_reg; ---------------------------------------------------------------- -- Guarded Signal Parameters ---------------------------------------------------------------- ---------------------------------------------------------------- -- 23.1.2 Blocks and Guarded Signal Assignment ---------------------------------------------------------------- -- Example 23.3, Page 740 architecture dataflow of processor_node is signal address_bus : resolve_unique word bus; ... begin cache_to_address_buffer : block ( cache_miss and dirty ) is begin address_bus <= guarded tag_section0 & set_index & B"0000" when replace_section = '0' else tag_section1 & set_index & B"0000"; end block cache_to_address_buffer; snoop_to_address_buffer : block ( snoop_hit and flag_update ) is begin address_bus <= guarded snoop_address(31 downto 4) & B"0000"; end block snoop_to_address_buffer; ... end architecture dataflow; -- Example 23.4, Page 742 entity latch is generic ( width : positive ); port ( enable : in bit; d : in bit_vector(0 to width - 1); q : out bit_vector(0 to width - 1) ); end entity latch; -------------------------------------------------- architecture behavioral of latch is begin transfer_control : block ( enable ) is begin q <= guarded d; end block transfer_control; end architecture behavioral; ---------------------------------------------------------------- -- Explicit Guard Signals ---------------------------------------------------------------- ---------------------------------------------------------------- -- Disconnection Specifications ---------------------------------------------------------------- -- Page 743 signal memory_data_bus : resolved_word bus; disconnect memory_data_bus : resolved_word after 3 ns; mem_write_buffer : block (mem_sel and mem_write) is begin memory_data_bus <= guarded reject 2 ns inertial cache_data_bus after 4 ns; end block mem_write_buffer; -- Page 744 signal source_bus_1, source_bus_2 : resolved_word bus; signal address_bus : resolved_word bus; disconnect all : resolved_word after 2 ns; disconnect address_bus : resolved_word after 3 ns; disconnect others : resolved_word after 2 ns; ---------------------------------------------------------------- -- 23.1.3 Using Blocks for Structural Modularity ---------------------------------------------------------------- -- Example 23.5, Page 745 entity counter is generic ( tipd_reset, -- input prop delay on reset tipd_clk, -- input prop delay on clk topd_q : delay_length; -- output prop delay on q tsetup_reset, -- setup: reset before clk thold_reset : -- hold time: reset after clk delay_length ); port ( reset, -- synchronous reset input clk : in bit; -- edge-triggered clock input q : out bit_vector ); -- counter output end entity counter; architecture detailed_timing of counter is signal reset_ipd, -- data input port delayed clk_ipd : bit; -- clock input port delayed signal q_zd : bit_vector(q'range); -- q output with zero delay begin input_port_delay : block is begin reset_ipd <= reset after tipd_reset; clk_ipd <= clk after tipd_clk; end block input_port_delay; functionality : block is function increment ( bv : bit_vector ) return bit_vector is variable result : bit_vector(bv'range) := bv; variable carry : bit := '1'; begin for index in result'reverse_range loop result(index) := bv(index) xor carry; carry := bv(index) and carry; exit when carry = '0'; end loop; return result; end function increment; signal next_count : bit_vector(q'range); begin next_count <= increment(q_zd) when reset_ipd = '0' else (others => '0'); q_zd <= next_count when clk_ipd = '1' and clk_ipd'event; end block functionality; output_port_delay : block is begin q <= q_zd after topd_q; end block output_port_delay; timing_checks : block is begin -- check setup time: reset before clk ... -- check hold time: reset after clk ... end block timing_checks; end architecture detailed_timing; ---------------------------------------------------------------- -- External Names and Blocks ---------------------------------------------------------------- -- Example 23.6, Page 747 architecture verifying of test_bench is signal clk, reset : bit; signal duv_q : bit_vector(7 downto 0); alias duv_next_count is <>; ... begin duv : entity work.counter(detailed_timing) generic map ( ... ) port map ( clk => clk, reset => reset, q => duv_q ); ... end architecture verifying; ---------------------------------------------------------------- -- Generics and Ports in Blocks ---------------------------------------------------------------- ---------------------------------------------------------------- -- Configuring Designs with Blocks ---------------------------------------------------------------- -- Example 23.7, Page 749 entity circuit is generic ( inpad_delay, outpad_delay : delay_length ); port ( in1, in2, in3 : in bit; out1, out2 : out bit ); end entity circuit; -------------------------------------------------- architecture with_pad_delays of circuit is component subcircuit is port ( a, b : in bit; y1, y2 : out bit ); end component subcircuit; signal delayed_in1, delayed_in2, delayed_in3 : bit; signal undelayed_out1, undelayed_out2 : bit; begin input_delays : block is begin delayed_in1 <= in1 after inpad_delay; delayed_in2 <= in2 after inpad_delay; delayed_in3 <= in3 after inpad_delay; end block input_delays; functionality : block is signal intermediate : bit; begin cell1 : component subcircuit port map ( delayed_in1, delayed_in2, undelayed_out1, intermediate ); cell2 : component subcircuit port map ( intermediate, delayed_in3, undelayed_out2, open ); end block functionality; output_delays : block is begin out1 <= undelayed_out1 after outpad_delay; out2 <= undelayed_out2 after outpad_delay; end block output_delays; end architecture with_pad_delays; -- Example 23.7, Page 750 configuration full of circuit is for with_pad_delays -- configure the architecture for functionality -- configure the block for all : subcircuit use entity work.real_subcircuit(basic); end for; end for; end for; end configuration full; ---------------------------------------------------------------- -- 23.2 IP Encryption ---------------------------------------------------------------- -- Example 23.8, Page 754 entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect data_keyowner = "ACME IP User" `protect data_keyname = "ACME Sim Key" `protect data_method = "aes192-cbc" `protect encoding = (enctype = "base64") `protect begin signal ... begin process ... ... `protect end end architecture RTL; entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect begin_protected `protect encrypt_agent = "Encryptomatic" `protect encrypt_agent_info = "2.3.4a" `protect data_keyowner = "ACME IP User" `protect data_keyname = "ACME Sim Key" `protect data_method = "aes192-cbc" `protect encoding=(enctype="base64", line_length=40, bytes=4006) `protect data_block encoded cipher-text ... `protect end_protected end architecture RTL; -- Example 23.9, Page 755 entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect key_keyowner = "ACME IP User" `protect key_keyname = "ACME Sim Key" `protect key_method = "rsa" `protect key_block `protect data_method = "aes192-cbc" `protect encoding = (enctype = "base64") `protect begin signal ... begin process ... ... `protect end end architecture RTL; -- Example 23.9, Page 756 entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect begin_protected `protect encrypt_agent = "Encryptomatic" `protect encrypt_agent_info = "2.3.4a" `protect key_keyowner = "ACME IP User" `protect key_keyname = "ACME Sim Key" `protect key_method = "rsa" `protect encoding=(enctype="base64", line_length=40, bytes=256) `protect key_block encoded cipher-text for session key `protect data_method = "aes192-cbc" `protect encoding=(enctype="base64", line_length=40, bytes=4006) `protect data_block encoded cipher-text for model code ... `protect end_protected end architecture RTL; -- Example 23.10, Page 757 entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect key_keyowner = "ACME IP User1" `protect key_keyname = "ACME Sim Key" `protect key_method = "rsa" `protect key_block `protect key_keyowner = "ACME IP User2" `protect key_keyname = "ACME Synth Key" `protect key_method = "elgamal" `protect key_block `protect key_keyowner = "ACME IP User3" `protect key_keyname = "ACME P&R Key" `protect key_method = "aes192-cbc" `protect key_block `protect data_method = "aes192-cbc" `protect encoding = (enctype = "base64") `protect begin signal ... begin process ... ... `protect end end architecture RTL; -- Example 23.10, Page 758 entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect begin_protected `protect encrypt_agent = "Encryptomatic" `protect encrypt_agent_info = "2.3.4a" `protect key_keyowner = "ACME IP User1" `protect key_keyname = "ACME Sim Key" `protect key_method = "rsa" `protect encoding=(enctype="base64", line_length=40, bytes=256) `protect key_block encoded cipher-text for session key `protect key_keyowner = "ACME IP User2" `protect key_keyname = "ACME Synth Key" `protect key_method = "elgamal" `protect encoding=(enctype="base64", line_length=40, bytes=256) `protect key_block encoded cipher-text for session key `protect key_keyowner = "ACME IP User3" `protect key_keyname = "ACME P&R Key" `protect key_method = "aes192-cbc" `protect encoding=(enctype="base64", line_length=40, bytes=256) `protect key_block encoded cipher-text for session key `protect data_method = "aes192-cbc" `protect encoding=(enctype="base64", line_length=40, bytes=4006) `protect data_block encoded cipher-text for model code ... `protect end_protected end architecture RTL; -- Example 23.11, Page 759 entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect key_keyowner = "ACME IP User" `protect key_keyname = "ACME Sim Key" `protect key_method = "rsa" `protect key_block `protect data_method = "aes192-cbc" `protect digest_keyowner = "GoodGuys IP Author" `protect digest_keyname = "GoodGuys Signing Key" `protect digest_key_method = "rsa" `protect digest_method = "sha1" `protect digest_block `protect encoding = (enctype = "base64") `protect begin signal ... begin process ... ... `protect end end architecture RTL; entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect begin_protected `protect encrypt_agent = "Encryptomatic" `protect encrypt_agent_info = "2.3.4a" `protect key_keyowner = "ACME IP User" `protect key_keyname = "ACME Sim Key" `protect key_method = "rsa" `protect encoding=(enctype="base64", line_length=40, bytes=256) `protect key_block encoded cipher-text for session key `protect data_method = "aes192-cbc" `protect encoding=(enctype="base64", line_length=40, bytes=4006) `protect data_block encoded cipher-text for model code ... `protect digest_keyowner = "GoodGuys IP Author" `protect digest_keyname = "GoodGuys Signing Key" `protect digest_key_method = "rsa" `protect digest_method = "sha1" `protect digest_block `protect encoding=(enctype="base64", line_length=40, bytes=16) `protect digest_block encoded cipher-text for digest ... `protect end_protected end architecture RTL; -- Example 23.12, Page 761 entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect data_keyowner = "ACME IP User" `protect data_keyname = "ACME Sim Key" `protect data_method = "aes192-cbc" `protect encoding = (enctype = "base64") `protect viewport=(object="accelerator:RTL.state", access="RW"); `protect begin signal state : std_ulogic_vector(3 downto 0); . .. begin process ... ... `protect end end architecture RTL; entity accelerator is port ( ... ); end entity accelerator; architecture RTL of accelerator is `protect begin_protected `protect encrypt_agent = "Encryptomatic" `protect encrypt_agent_info = "2.3.4a" `protect viewport=(object="accelerator:RTL.state", access="RW"); `protect data_keyowner = "ACME IP User" `protect data_keyname = "ACME Sim Key" `protect data_method = "aes192-cbc" `protect encoding=(enctype="base64", line_length=40, bytes=4006) `protect data_block encoded cipher-text ... `protect end_protected end architecture RTL; -- Example 23.12, Page 762 architecture monitoring of tb is ... begin ... -- clock and reset generation accelerator_duv : entity work.accelerator(rtl) port map ( ... ); monitor : process (clk) is use std.textio.all; file state_file : text open write_mode is state_file_name; alias accelerator_state is <>; begin if falling_edge(clk) then write(L, accelerator_state); writeline(state_file, L); end if; end process monitor; end architecture monitoring; ---------------------------------------------------------------- -- 23.2.1 Key Exchange ---------------------------------------------------------------- ---------------------------------------------------------------- -- 23.3 VHDL Procedural Interface (VHPI) ---------------------------------------------------------------- -- Page 770 attribute foreign : string; ---------------------------------------------------------------- -- 23.3.1 Direct Binding ---------------------------------------------------------------- -- Example 23.13, Page 772 entity cpu32 is generic ( ... ); port ( ... ); end entity cpu_32; architecture bus_functional of cpu32 is attribute foreign of bus_functional : architecture is "VHPIDIRECT /usr/local/cpu32/cpu32.a " & "cpu32_bf_elab_f cpu32_bf_exec_f"; begin end architecture bus_functional; -- Example 23.14, Page 772 package display_pkg is impure function create_digit (title : in string) return natural; attribute foreign of create_digit : function is "VHPIDIRECT displaylib.a null"; procedure update_digit (id : in natural; val : in bit_vector(0 to 7)); attribute foreign of update_digit : procedure is "VHPIDIRECT displaylib.a null"; end package display_pkg; ---------------------------------------------------------------- -- 23.3.2 Tabular Registration and Indirect Binding ---------------------------------------------------------------- -- Example 23.15, Page 774 architecture bus_functional of cpu32 is attribute foreign of bus_functional : architecture is "VHPI cpu32lib \cpu32-bf\"; begin end architecture bus_functional; -- Example 23.16, Page 774 package display_pkg is impure function create_digit (title : in string) return natural; attribute foreign of create_digit : function is "VHPI displaylib create_digit"; procedure update_digit (id : in natural; val : in bit_vector(0 to 7)); attribute foreign of update_digit : procedure is "VHPI displaylib update_digit"; end package display_pkg; ---------------------------------------------------------------- -- 23.3.3 Registration of Applications and Libraries ---------------------------------------------------------------- ---------------------------------------------------------------- -- 23.4 Postponed Processes ---------------------------------------------------------------- -- Example 23.18, Page 777 entity SR_flipflop is port ( s_n, r_n : in bit; q, q_n : inout bit ); begin postponed process (q, q_n) is begin assert now = 0 fs or q = not q_n report "implementation error: q /= not q_n"; end postponed process; end entity SR_flipflop; architecture dataflow of SR_flipflop is begin gate_1 : q <= s_n nand q_n; gate_2 : q_n <= r_n nand q; end architecture dataflow; -- Page 778 p : postponed process is ... begin ... wait until s = '1'; ... -- s may not be '1'!! end postponed process p; -- Page 779 postponed assert now = 0 fs or q = not q_n report "implementation error: q /= not q_n"; ---------------------------------------------------------------- -- 23.5 Conversion Functions in Association Lists ---------------------------------------------------------------- -- Example 23.19, Page 780 subtype word is std_ulogic_vector(31 downto 0); function "<" ( bv1, bv2 : bit_vector ) return boolean; library ieee; use ieee.std_logic_1164.all; use work.project_util.all; entity limit_checker is port ( input, lower_bound, upper_bound : in word; out_of_bounds : out std_ulogic ); end entity limit_checker; -------------------------------------------------- architecture behavioral of limit_checker is subtype bv_word is bit_vector(31 downto 0); function word_to_bitvector ( w : in word ) return bv_word is begin return To_bitvector ( w, xmap => '0' ); end function word_to_bitvector; begin algorithm : process (input, lower_bound, upper_bound) is begin if "<" ( bv1 => word_to_bitvector(input), bv2 => word_to_bitvector(lower_bound) ) or "<" ( bv1 => word_to_bitvector(upper_bound), bv2 => word_to_bitvector(input) ) then out_of_bounds <= '1'; else out_of_bounds <= '0'; end if; end process algorithm; end architecture behavioral; -- Example 23.20, Page 781 function increment ( x : unsigned ) return unsigned; op_counter : component reg16 port map ( d_in => increment(op_count), ... ); -- Example 23.20, Page 782 op_counter : component reg16 port map ( d_in => inertial increment(op_count), ... ); -- Example 23.21, Page 782 entity random_source is generic ( min, max : natural; seed : natural; interval : delay_length ); port ( number : out natural ); end entity random_source; architecture random_test of test_bench is subtype bv11 is bit_vector(10 downto 0); function natural_to_bv11 ( n : natural ) return bv11 is variable result : bv11 := (others => '0'); variable remaining_digits : natural := n; begin for index in result'reverse_range loop result(index) := bit'val(remaining_digits mod 2); remaining_digits := remaining_digits / 2; exit when remaining_digits = 0; end loop; return result; end function natural_to_bv11; signal stimulus_vector : bv11; ... begin stimulus_generator : entity work.random_source generic map ( min => 0, max => 2**10 - 1, seed => 0, interval => 100 ns ) port map ( natural_to_bv11(number) => stimulus_vector ); ... end architecture random_test; -- Page 784 type std_ulogic_vector is array (natural range <>) of std_ulogic; type std_logic_vector is array (natural range <>) of std_logic; -- Example 23.22, Page 784 architecture rtl of processor is component latch is generic ( width : positive ); port ( d : in std_ulogic_vector(0 to width - 1); q : out std_ulogic_vector(0 to width - 1); ... ); end component latch; component ROM is port ( d_out : out std_ulogic_vector; ... ); end component ROM; subtype std_logic_word is std_logic_vector(0 to 31); signal source1, source2, destination : std_logic_word; ... begin temp_register : component latch generic map ( width => 32 ) port map ( d => std_ulogic_vector(destination), std_logic_vector(q) => source1, ... ); constant_ROM : component ROM port map ( std_logic_word(d_out) => source2, ... ); ... end architecture rtl; ---------------------------------------------------------------- -- 23.6 Linkage Ports ---------------------------------------------------------------- ---------------------------------------------------------------- -- Exercises ---------------------------------------------------------------- -- Exercise 5 result <= 0 after 10 ns, 42 after 20 ns, 0 after 100 ns, null after 120 ns; -- Exercise 8 signal request : integer := 0; signal guard : boolean := false; signal priority : resolved_integer bus := 0; disconnect priority : resolved_integer after 2 ns; ... request <= 3 after 40 ns, 5 after 80 ns, 1 after 120 ns; guard <= true after 50 ns, false after 100 ns; priority <= guarded request after 1 ns; -- Exercise 11 architecture rtl of ethernet_mac is signal fifo_enable : std_ulogic; ... begin rx_fifo : IP_werx_fifo port map ( ... ); ... end architecture rtl; -- Exercise 13 architecture vhpi_implementation of control is begin end architecture vhpi_implementation; -- Exercise 16 component nand2 is port ( a, b : in std_ulogic; y_n : out std_ulogic ); end component nand2; -- Exercise 17 subtype word is bit_vector(31 downto 0); ... subtype resolved_word is bitwise_or word;