150 likes | 268 Vues
This document provides a comprehensive overview of subprograms in VHDL, focusing on procedures and functions. It explains the structure and components of subprogram declarations, including formal parameters and return types. Practical examples illustrate the implementation of these subprograms, such as the calculation of averages and handling arithmetic operations. The document also discusses important concepts like overloading and concurrent procedure calls, helping readers to grasp the functionality and versatility of VHDL subprograms in digital design.
E N D
Subprograms subprogram_body <= procedure designator [ ( formal_parameter_list ) ] | function designator [ ( formal_parameter_list ) ] return type_mark subprogram_declarative_part begin subprogram_statement_part end [ designator ] ;
Procedure example entity fg_07_01 is end entity fg_07_01; architecture test of fg_07_01 is procedure average_test is variable average : real := 0.0; type sample_array is array (positive range <>) of real; constant samples : sample_array := ( 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 ); procedure average_samples is variable total : real := 0.0; begin assert samples'length > 0 severity failure; for index in samples'range loop total := total + samples(index); end loop; average := total / real(samples'length); end procedure average_samples; begin average_samples; end procedure average_test; begin average_test; end architecture test;
Procedure parameters interface_declaration ::= interface_constant_declaration | interface_signal_declaration | interface_variable_declaration interface_constant_declaration ::= [ constant ] identifier_list : [ in ] subtype_indication [ := static_expression ] interface_signal_declaration ::= [ signal ] identifier_list : [ mode ] subtype_indication [ := static_expression ] interface_variable_declaration ::= [ variable ] identifier_list : [ mode ] subtype_indication [ := static_expression ] mode ::= in | out | inout
Example procedure addu ( a, b : in word32; result : out word32; overflow : out boolean ) is variable sum : word32; variable carry : bit := '0'; begin for index in sum'reverse_range loop sum(index) := a(index) xor b(index) xor carry; carry := ( a(index) and b(index) ) or ( carry and ( a(index) xor b(index) ) ); end loop; result := sum; overflow := carry = '1'; end procedure addu;
Signal parameters • Mode: in • singal passed as a reference • if the procedure executes a wait statement the signal value may be different • Mode: out • reference to the driver of the signal is passed • Mode: inout • both the signal and its driver is passed as a reference
Concurrent procedure call procedure p ( signal s1, s2 : in bit; val1 : in integer ); call_proc : process is begin p ( s1, s2, val1 ); wait on s1, s2; end process call_proc; call_proc : p ( s1, s2, val1 );
Example function architecture test of fg_07_17 is function bv_to_natural ( bv : in bit_vector ) return natural is variable result : natural := 0; begin for index in bv'range loop result := result * 2 + bit'pos(bv(index)); end loop; return result; end function bv_to_natural; signal data : bit_vector(0 to 7); constant address : bit_vector(0 to 3) := "0101"; constant Taccess : delay_length := 80 ns; begin tester : process is constant rom_size : natural := 8; constant word_size : natural := 8; type rom_array is array (natural range 0 to rom_size-1) of bit_vector(0 to word_size-1); variable rom_data : rom_array; begin rom_data := (X"00", X"01", X"02", X"03", X"04", X"05", X"06", X"07"); data <= rom_data ( bv_to_natural(address) ) after Taccess; wait; end process tester; end architecture test;
Overloading • Two distinct subprograms with • same name • different numbers or • different types of formal parameters
Example architecture test of ch_07_05 is begin process_07_5_a : process is procedure increment ( a : inout integer; n : in integer := 1 ) is begin a := a + n; end procedure increment; procedure increment ( a : inout bit_vector; n : in bit_vector := B"1" ) is begin a := bit_vector(signed(a) + signed(n)); end procedure increment; procedure increment ( a : inout bit_vector; n : in integer := 1 ) is begin a := bit_vector(signed(a) + to_signed(n, a'length)); end procedure increment; variable count_int : integer := 2; variable count_bv : bit_vector (15 downto 0) := X"0002"; begin increment ( count_int, 2 ); increment ( count_int ); increment ( count_bv, X"0002"); increment ( count_bv, 1 ); -- increment ( count_bv ); -- Illegal!!! wait; end process process_07_5_a; end architecture test;
Overloading Operator Symbols architecture test of ch_07_06 is begin process_07_5_b : process is function "+" ( left, right : in bit_vector ) return bit_vector is begin return bit_vector( "+"(signed(left), signed(right)) ); end function "+"; variable addr_reg : bit_vector(31 downto 0); function "abs" ( right : in bit_vector ) return bit_vector is begin if right(right'left) = '0' then return right; else return bit_vector( "-"(signed(right)) ); end if; end function "abs"; variable accumulator : bit_vector(31 downto 0); begin addr_reg := addr_reg + X"0000_0004"; accumulator := X"000000FF"; accumulator := abs accumulator; accumulator := X"FFFFFFFE"; accumulator := abs accumulator; wait; end process process_07_5_b; end architecture test;
Mealy State-Machine Moore State-Machine State machine types
One-hot Each state is associated with a unique bit S1 <= ”0001” S2 <= ”0010” S3 <= ”0100” S4 <= ”1000” large state register easy to decode state Binary Encoding Each state is associated with a unique number S1 <= ”00” S2 <= ”01” S3 <= ”10” S4 <= ”11” small state register harder to decode state State encoding
type state_type is (st1_<name_state>, st2_<name_state>, ...); signal state, next_state : state_type; signal <output>_i : std_logic; SYNC_PROC: process (<clock>) begin if (<clock>'event and <clock> = '1') then if (<reset> = '1') then state <= st1_<name_state>; <output> <= '0'; else state <= next_state; <output> <= <output>_i; end if; end if; end process; OUTPUT_DECODE: process (state, <input1>, <input2>, ...) begin if (state = st3_<name> and <input1> = '1') then <output>_i <= '1'; else <output>_i <= '0'; end if; end process; NEXT_STATE_DECODE: process (state, <input1>, <input2>, ...) begin next_state <= state; case (state) is when st1_<name> => if <input_1> = '1' then next_state <= st2_<name>; end if; when st2_<name> => if <input_2> = '1' then next_state <= st3_<name>; end if; when st3_<name> => next_state <= st1_<name>; when others => next_state <= st1_<name>; end case; end process; Mealy State-Machine
type state_type is (st1_<name_state>, st2_<name_state>, ...); signal state, next_state : state_type; signal <output>_i : std_logic; SYNC_PROC: process (<clock>) begin if (<clock>'event and <clock> = '1') then if (<reset> = '1') then state <= st1_<name_state>; <output> <= '0'; else state <= next_state; <output> <= <output>_i; end if; end if; end process; OUTPUT_DECODE: process (state) begin if state = st3_<name> then <output>_i <= '1'; else <output>_i <= '0'; end if; end process; NEXT_STATE_DECODE: process (state, <input1>, <input2>, ...) begin next_state <= state; case (state) is when st1_<name> => if <input_1> = '1' then next_state <= st2_<name>; end if; when st2_<name> => if <input_2> = '1' then next_state <= st3_<name>; end if; when st3_<name> => next_state <= st1_<name>; when others => next_state <= st1_<name>; end case; end process; Moore State-Machine