330 likes | 420 Views
SUBPROGRAMAS. PROCEDIMENTOS. 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);
E N D
SUBPROGRAMAS • PROCEDIMENTOS 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; Declarações comandos seqüenciais
architecture rtl of control_processor is type func_code is (add, subtract); signal op1, op2, dest : integer; signal Z_flag : boolean; signal func : func_code; . . . begin alu : process is procedure do_arith_op is variable result : integer; begin case func is when add => result := op1 + op2; when subtract => result := op1 - op2; end case; dest <= result after Tpd; Z_flag <= result = 0 after Tpd; end procedure do_arith_op; begin . . . do_arith_op; . . . end process alu; ... end process alu;
instruction_interpreter : process is variable mem_address_reg, mem_data_reg, prog_counter, instr_reg, accumulator, index_reg : word; . . . procedure read_memory is begin address_bus <= mem_address_reg; mem_read <= '1'; mem_request <= '1'; wait until mem_ready = '1'; mem_data_reg := data_bus_in; mem_request <= '0'; wait until mem_ready = '0'; end procedure read_memory;
begin . . . -- initialization loop -- fetch next instruction mem_address_reg := prog_counter; read_memory; -- call procedure instr_reg := mem_data_reg; -- . . . case opcode is -- . . . when load_mem => mem_address_reg := index_reg + displacement; read_memory; -- call procedure accumulator := mem_data_reg; -- . . . end case; end loop; end process instruction_interpreter;
control_sequencer : process is procedure control_write_back is begin wait until phase1 = '1'; reg_file_write_en <= '1'; wait until phase2 = '0'; reg_file_write_en <= '0'; end procedure control_write_back; procedure control_arith_op is begin wait until phase1 = '1'; A_reg_out_en <= '1'; B_reg_out_en <= '1'; wait until phase1 = '0'; A_reg_out_en <= '0'; B_reg_out_en <= '0'; wait until phase2 = '1'; C_reg_load_en <= '1'; wait until phase2 = '0'; C_reg_load_en <= '0'; control_write_back; -- call procedure end procedure control_arith_op;
RETURN instruction_interpreter : process is . . . procedure read_memory is begin address_bus <= mem_address_reg; mem_read <= '1'; mem_request <= '1'; wait until mem_ready = '1' or reset = '1'; if reset = '1' then return; end if; mem_data_reg := data_bus_in; mem_request <= '0'; wait until mem_ready = '0'; end procedure read_memory; begin . . . -- initialization loop . . . read_memory; exit when reset = '1'; . . . end loop; end process instruction_interpreter;
Parâmetros • IN --- constant procedure do_arith_op ( op : in func_code ) is variable result : integer; begin case op is when add => result := op1 + op2; when subtract => result := op1 - op2; end case; dest <= result after Tpd; Z_flag <= result = 0 after Tpd; end procedure do_arith_op; procedure do_arith_op ( op : func_code ) is
OUT --- Variable 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; variable PC, next_PC : word32; variable overflow_flag : boolean; ... begin PC := X"0000_0010"; addu ( PC, X"0000_0004", next_PC, overflow_flag);
INOUT -- variable procedure negate ( a : inout word32 ) is variable carry_in : bit := '1'; variable carry_out : bit; begin a := not a; for index in a'reverse_range loop carry_out := a(index) and carry_in; a(index) := a(index) xor carry_in; carry_in := carry_out; end loop; end procedure negate; variable op1 : word32; . . . begin op1 := X"0000_0002"; negate ( op1 );
architecture behavioral of receiver is . . . -- type declarations, etc signal recovered_data : bit; signal recovered_clock : bit; . . . procedure receive_packet ( signal rx_data : in bit; signal rx_clock : in bit; data_buffer : out packet_array ) is begin for index in packet_index_range loop wait until rx_clock = '1'; data_buffer(index) := rx_data; end loop; end procedure receive_packet; begin packet_assembler : process is variable packet : packet_array; begin . . . receive_packet ( recovered_data, recovered_clock, packet ); . . . end process packet_assembler; . . . end architecture behavioral; • SIGNAL -- in out inout
library ieee; use ieee.std_logic_1164.all; architecture top_level of signal_generator is signal raw_signal : std_ulogic; . . . procedure generate_pulse_train ( width, separation : in delay_length; number : in natural; signal s : out std_ulogic ) is begin for count in 1 to number loop s <= '1', '0' after width; wait for width + separation; end loop; end procedure generate_pulse_train; begin raw_signal_generator : process is begin . . . generate_pulse_train ( width => period / 2, separation => period - period / 2, number => pulse_count, s => raw_signal ); . . . end process raw_signal_generator; . . . end architecture top_level;
subtype word32 is bit_vector(31 downto 0); procedure increment ( a : inout word32; by : in word32 := X"0000_0001" ) is variable sum : word32; variable carry : bit := '0'; begin for index in a'reverse_range loop sum(index) := a(index) xor by(index) xor carry; carry := ( a(index) and by(index) ) or ( carry and ( a(index) xor by(index) ) ); end loop; a := sum; end procedure increment; • Valores default increment(count, X"0000_0004"); increment(count); increment(count, by => open);
procedure find_first_set ( v : in bit_vector; found : out boolean; first_set_index : out natural ) is begin for index in v'range loop if v(index) = '1' then found := true; first_set_index := index; return; end if; end loop; found := false; end procedure find_first_set; variable int_req : bit_vector (7 downto 0); variable top_priority : natural; variable int_pending : boolean; find_first_set ( int_req, int_pending, top_priority ); constant block_count : natural := 16; variable free_block_map : bit_vector(0 to block_count-1); variable first_free_block : natural; variable free_block_found : boolean; find_first_set ( free_block_map, free_block_found, first_free_block );
type t1 is (t1_1, t1_2); type t2 is (t2_1, t2_2); type t3 is (t3_1, t3_2); type t4 is (t4_1, t4_2); constant v4 : t4 := t4_1; constant val1 : t1 := t1_1; constant val2 : t2 := t2_1; variable var3 : t3 := t3_1; constant val4 : t4 := t4_1; procedure p ( f1 : in t1; f2 : in t2; f3 : out t3; f4 : in t4 := v4 ) is begin . . . end procedure p; p ( val1, val2, var3, val4 ); p ( f1 => val1, f2 => val2, f4 => val4, f3 => var3 ); p ( val1, val2, f4 => open, f3 => var3 ); p ( val1, val2, var3 );
Chamada de procedimento concorrente procedure p ( signal s1, s2 : in bit; val1 : in integer ) is begin null; end procedure p; call_proc : process is begin p ( s1, s2, val1 ); wait on s1, s2; end process call_proc; call_proc : p ( s1, s2, val1 );
Funções function limit ( value, min, max : integer ) return integer is begin if value > max then return max; elsif value < min then return min; else return value; end if; end function limit; new_temperature := limit ( current_temperature + increment, 10, 100 ); new_motor_speed := old_motor_speed + scale_factor * limit ( error, -10, +10 );
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;
Funções puras e impuras network_driver : process is constant seq_modulo : natural := 2**5; subtype seq_number is natural range 0 to seq_modulo-1; variable next_seq_number : seq_number := 0; . . . impure function generate_seq_number return seq_number is variable number : seq_number; begin number := next_seq_number; next_seq_number := (next_seq_number + 1) mod seq_modulo; return number; end function generate_seq_number; begin -- network_driver . . . new_header := pkt_header'( dest => target_host_id, src => my_host_id, pkt_type => control_pkt, seq => generate_seq_number ); . . . end process network_driver;
Overloading procedure increment ( a : inout integer; n : in integer := 1 ) is . . .; procedure increment ( a : inout bit_vector; n : in bit_vector := B"1" ) is . . .; procedure increment ( a : inout bit_vector; n : in integer := 1 ) is . . . variable count_int : integer := 2; variable count_bv : bit_vector (15 downto 0) := X"0002"; increment ( count_int, 2 ); increment ( count_int ); increment ( count_bv, X"0002"); increment ( count_bv, 1 ); increment ( count_bv ); -- erro
Overloading símbolos de operadores function "+" ( left, right : in bit_vector ) return bit_vector is begin . . . end function "+"; variable addr_reg : bit_vector(31 downto 0); function "abs" ( right : in bit_vector ) return bit_vector is begin . . . end function "abs"; ariable accumulator : bit_vector(31 downto 0); addr_reg := addr_reg + X"0000_0004"; accumulator := abs accumulator;
ALIASES package alu_types is constant data_width : positive := 32; end package alu_types; package io_types is constant data_width : positive := 32; end package io_types; library ieee; use ieee.std_logic_1164.all; use work.alu_types.all, work.io_types.all; architecture structural of controller_system is alias alu_data_width is work.alu_types.data_width; alias io_data_width is work.io_types.data_width; signal alu_in1, alu_in2, alu_result : std_logic_vector(0 to alu_data_width - 1); signal io_data : std_logic_vector(0 to io_data_width - 1);
type register_array is array (0 to 15) of bit_vector(31 downto 0); type register_set is record general_purpose_registers : register_array; program_counter : bit_vector(31 downto 0); program_status : bit_vector(31 downto 0); end record; variable CPU_registers : register_set; alias PSW is CPU_registers.program_status; alias PC is CPU_registers.program_counter; alias GPR is CPU_registers.general_purpose_registers; alias SP : bit_vector(31 downto 0) is CPU_registers.general_purpose_registers(15); alias interrupt_level is PSW(30 downto 26);
function "+" ( bv1, bv2 : bit_vector ) return bit_vector is alias norm1 : bit_vector(1 to bv1'length) is bv1; alias norm2 : bit_vector(1 to bv2'length) is bv2; variable result : bit_vector(1 to bv1'length); variable carry : bit := '0'; begin if bv1'length /= bv2'length then report "arguments of different length" severity failure; else for index in norm1'reverse_range loop result(index) := norm1(index) xor norm2(index) xor carry; carry := ( norm1(index) and norm2(index) ) or ( carry and ( norm1(index) or norm2(index) ) ); end loop; end if; return result; end function "+";
Resolved Signals Resolved Signals - Usados para modelar sinais multiply-driven Na prática os sinais podem ter múltiplas fontes e devem ser modelados como tal Em VHDL a declaração de resolved signal deve incluir a função de resolução que será usada para determinar o valor do sinal
Funções de Resolução Funções de resolução são usadas para descrever o comportamento do sinal quando submetido às diversas combinações possíveis dos sinais fontes. Exemplo: Type my_type is (X, Z, 0, 1); Type my_type_vector is array (natural range <>) of my_type; function resolve_my_type (a: my_type_vector) return my_type is variable temp: my_type := Z; begin for i in a´range loop case temp is when Z => case a(i) is when X => temp := X; when Z => temp := Z; when 0 => temp := 0; when 1 => temp := 1; end case; when X => temp := X; when 0 => case a(i) is when X => temp := X; when Z => temp := 0; when 0 => temp := 0; when 1 => temp := X; end case; ........ return temp; end tesolv_my_type;
Funções de Resolução entity fg_11_01 is end entity fg_11_01; architecture test of fg_11_01 is type tri_state_logic is ('0', '1', 'Z'); type tri_state_logic_array is array (integer range <>) of tri_state_logic; function resolve_tri_state_logic ( values : in tri_state_logic_array ) return tri_state_logic is variable result : tri_state_logic := 'Z'; begin for index in values'range loop if values(index) /= 'Z' then result := values(index); end if; end loop; return result; end function resolve_tri_state_logic; signal s1 : resolve_tri_state_logic tri_state_logic; subtype resolved_logic is resolve_tri_state_logic tri_state_logic; signal s2, s3 : resolved_logic; begin source_1 : s1 <= 'Z', '0' after 10 ns, 'Z' after 20 ns, '1' after 30 ns, 'Z' after 40 ns, '1' after 200 ns, 'Z' after 220ns; source_2 : s1 <= 'Z', '0' after 110 ns, 'Z' after 120 ns, '1' after 130 ns, 'Z' after 140 ns, '1' after 200 ns, '0' after 210 ns, 'Z' after 220 ns; end architecture test;
package MVL4 is type MVL4_ulogic is ('X', '0', '1', 'Z'); -- unresolved logic type type MVL4_ulogic_vector is array (natural range <>) of MVL4_ulogic; function resolve_MVL4 ( contribution : MVL4_ulogic_vector ) return MVL4_ulogic; subtype MVL4_logic is resolve_MVL4 MVL4_ulogic; type MVL4_logic_vector is array (natural range <>) of MVL4_logic; end package MVL4; package body MVL4 is type table is array (MVL4_ulogic, MVL4_ulogic) of MVL4_ulogic; constant resolution_table : table := -- 'X' '0' '1' 'Z' -- ------------------ ( ( 'X', 'X', 'X', 'X' ), -- 'X' ( 'X', '0', 'X', '0' ), -- '0' ( 'X', 'X', '1', '1' ), -- '1' ( 'X', '0', '1', 'Z' ) ); -- 'Z' function resolve_MVL4 ( contribution : MVL4_ulogic_vector ) return MVL4_ulogic is variable result : MVL4_ulogic := 'Z'; begin for index in contribution'range loop result := resolution_table(result, contribution(index)); end loop; return result; end function resolve_MVL4; end package body MVL4;
use work.MVL4.all; entity tri_state_buffer is port ( a, enable : in MVL4_ulogic; y : out MVL4_ulogic ); end entity tri_state_buffer; -------------------------------------------------- architecture behavioral of tri_state_buffer is begin y <= 'Z' when enable = '0' else a when enable = '1' and (a = '0' or a = '1') else 'X'; end architecture behavioral;
stimulus : process is begin wait for 10 ns; src1_enable <= '0'; src2_enable <= '0'; wait for 10 ns; src1 <= '0'; src2 <= '1'; wait for 10 ns; src1_enable <= '1'; wait for 10 ns; src1 <= 'Z'; wait for 10 ns; src1 <= '1'; wait for 10 ns; src1_enable <= '0'; wait for 10 ns; src2_enable <= '1'; wait for 10 ns; src2 <= 'Z'; wait for 10 ns; src2 <= '0'; wait for 10 ns; src2_enable <= '0'; wait for 10 ns; src1_enable <= '1'; src2_enable <= '1'; wait for 10 ns; src1 <= '0'; wait for 10 ns; src1 <= 'X'; wait for 10 ns; src1 <= '1'; src2 <= '1'; wait for 10 ns; wait; end process stimulus; end architecture gate_level; entity misc_logic is end entity misc_logic; use work.MVL4.all; architecture gate_level of misc_logic is signal src1, src1_enable : MVL4_ulogic; signal src2, src2_enable : MVL4_ulogic; signal selected_val : MVL4_logic; -- . . . begin src1_buffer : entity work.tri_state_buffer(behavioral) port map ( a => src1, enable => src1_enable, y => selected_val ); src2_buffer : entity work.tri_state_buffer(behavioral) port map ( a => src2, enable => src2_enable, y => selected_val ); -- . . .
package body words is type table is array (X01Z, X01Z) of X01Z; constant resolution_table : table := -- 'X' '0' '1' 'Z' -- ------------------ ( ( 'X', 'X', 'X', 'X' ), -- 'X' ( 'X', '0', 'X', '0' ), -- '0' ( 'X', 'X', '1', '1' ), -- '1' ( 'X', '0', '1', 'Z' ) ); -- 'Z' function resolve_word ( contribution : uword_vector ) return uword is variable result : uword := (others => 'Z'); begin for index in contribution'range loop for element in uword'range loop result(element) := resolution_table( result(element), contribution(index)(element) ); end loop; end loop; return result; end function resolve_word; end package body words; package words is type X01Z is ('X', '0', '1', 'Z'); type uword is array (0 to 31) of X01Z; type uword_vector is array (natural range <>) of uword; function resolve_word ( contribution : uword_vector ) return uword; subtype word is resolve_word uword; -- not in book type ubyte is array (0 to 7) of X01Z; -- end not in book end package words;
use work.words.all; entity cpu is port ( address : out uword; data : inout uword; other_port : in X01Z := 'Z' ); end entity cpu; architecture behavioral of cpu is begin end architecture behavioral; entity memory is port ( address : in uword; data : inout uword; other_port : in X01Z := 'Z' ); end entity memory; architecture behavioral of memory is begin end architecture behavioral; entity ROM is port ( a : in uword; d : out ubyte; other_port : in X01Z := 'Z' ); end entity ROM; architecture behavioral of ROM is begin end architecture behavioral; entity computer_system is end entity computer_system; architecture top_level of computer_system is use work.words.all; signal address : uword; signal data : word; begin the_cpu : entity work.cpu(behavioral) port map ( address, data, open ); the_memory : entity work.memory(behavioral) port map ( address, data, open ); end architecture top_level;
IEEE Std_Logic_1164 Resolved Subtypes package fg_11_08 is type std_ulogic is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-'); type std_ulogic_vector is array ( natural range <> ) of std_ulogic; function resolved ( s : std_ulogic_vector ) return std_ulogic; end package fg_11_08; package body fg_11_08 is type stdlogic_table is array (std_ulogic, std_ulogic) of std_ulogic; constant resolution_table : stdlogic_table := -- --------------------------------------------- -- 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-' -- --------------------------------------------- ( ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- 'U' ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- 'X' ( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- '0' ( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- '1' ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- 'Z' ( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- 'W' ( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- 'L' ( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- 'H' ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- '-' ); function resolved ( s : std_ulogic_vector ) return std_ulogic is variable result : std_ulogic := 'Z'; -- weakest state default begin if s'length = 1 then return s(s'low); else for i in s'range loop result := resolution_table(result, s(i)); end loop; end if; return result; end function resolved; -- end code from book end package body fg_11_08;