150 likes | 255 Views
Subprograms Procedures, functions. 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 ] ;.
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