subprogramas procedimentos e funções mo801/mc912
Post on 17-Apr-2015
110 Views
Preview:
TRANSCRIPT
SubprogramasProcedimentos e Funções
MO801/MC912
Conceitos Gerais
• Similar a outras linguagens de programação
• Procedimentos não retornam valores– statement
• Funções retornam valores– expression
• O hardware é replicado o número de vezes que a função/procedimento é chamada
Procedimentos
procedure read_memory isbegin
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;
Parâmetros
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;
Tipos de Parâmetros
• in– É visto como uma constante dentro do procedimento– Passagem por cópia
• out– É utilizado para retornar um valor– Não pode ser lido, só escrito– O valor é copiado para a variável externa ao final do
procedimento• inout
– Serve como entrada e saída– O valor é copiado para a variável externa ao final do
procedimento
Classes dos Parâmetros
• Especificam como o parâmetro deve ser visto pelo procedimento– variable
• Opção padrão para out e inout.
– constant• Opção padrão para in.
– signal• Pode ser usado com in, out e inout• Efeito de passagem por referência
Exemplo
procedure generate_pulse_train ( width, separation : in delay_length;
number : in natural; signal s : out std_ulogic ) is
beginfor count in 1 to number loop
s <= '1', '0' after width;wait for width + separation;
end loop;end procedure generate_pulse_train;
Uso
raw_signal_generator : process is
begin
generate_pulse_train ( width => period / 2,
separation => period - period / 2,
number => pulse_count,
s => raw_signal );
wait;
end process raw_signal_generator;
Localização
• Dentro de um processo– Pode acessar as variáveis do processo
• Dentro da arquitetura– Só pode acessar sinais– Deve declarar os parâmetros como sinais
Valor Padrão
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;
Valor Padrão
• Chamada com todos os parâmetros– increment(count, X”0000_0004”);
• Omitindo o último parâmetro– increment(count);
• Não especificando o último parâmetro– increment(count, open);
• As duas últimas alternativas são equivalentes• Dica: Use open quando o parâmetro não for o
último
Vetores sem limites
procedure find_first_set ( v : in bit_vector; found : out boolean; first_set_index : out natural ) is
beginfor index in v'range loop
if v(index) = '1' thenfound := true;first_set_index := index;return;
end if;end loop;found := false;
end procedure find_first_set;
Variações de Chamadas
• Procedimentoprocedure p(f1:in t1; f2:in t2; f3:out t3; f4:in t4 := v4) is
begin
…
end procedure p;
• Chamadasp(val1, val2, var3, val4);
p(f1 => val1, f2 => val2, f4 => val4, v3 => var3);
p(val1, val2, f4 => open, f3 => var3);
p(val1, val2, var3);
Chamadas em Comandos Concorrentes
• Quando chamados fora de processos, os procedimentos funcionam como se o código fosse:
call_proc : process is
begin
p(s1, s2, val1);
wait on s1, s2;
end process call_proc;
Chamadas em Comandos Concorrentes
• Se não existir sinal de entrada e o procedimento retornar, ele não será chamado novamente– Útil quando se quer chamar um procedimento
apenas uma vez– Boa forma de fazer checagem de dados
• O procedimento pode ser um laço que nunca retorna– Ele deve executar wait de tempos em tempos
Funções
• Devem retornar valor– Não podem encerrar sem retornar valor
• Parâmetros devem ser in• Funções Puras (pure)
– Não acessam variáveis nem sinais externos– Padrão de VHDL
• Funções Impuras (impure)– Podem retornar valores diferentes para duas
chamadas com os mesmos parâmetros
Exemplo
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;
Outro Exemplo
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;
Chamada
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;
data <= rom_data(bv_to_natural(address));
Overload
• Mais de uma declaração de função de um subprograma com o mesmo nome– procedure increment(a : inout integer; n : in
integer := 1) is …– procedure increment(a : inout bit_vector; in
bit_vector := B“1”) is …– procedure increment(a : inout bit_vector; in
integer := 1) is …
• A diferenciação é feita pelos tipos dos parâmetros
Overload de operadores
• Operadores podem ser sobrescritos
• Muito útil para definição de novos tipos
• As redefinição de operadores lógicos não fazem curto circuito
Exemplos
function “+”(left, right : in bit_vector) return bit_vector is
begin…
end function “+”;
function “abs”(right : in bit_vector) return bit_vector is
begin…
end function “abs”;
Regras de Escopo
• Similares às das outras linguagens
• Apenas os elementos mais internos são vistos quando há conflito de nomes
Pacotes
• Forma de encapsular código• Podem conter
– declarações de componentes– configurações– constantes– procedimentos– funções– tipos– etc…
Composição
• Cabeçalho do pacote– Visível externamente– Define as interfaces– Pode declarar uma constante sem valor
• Corpo do pacote– Contém as implementações– Define o valor da constante declarada no
cabeçalho
Exemplo de Cabeçalho
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;
Corpo do Pacotepackage 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 …
function "*" ( bv1, bv2 : bit_vector ) return bit_vector is begin if bv1(bv1'left) = '0' and bv2(bv2'left) = '0' then return mult_unsigned(bv1, bv2); elsif bv1(bv1'left) = '0' and bv2(bv2'left) = '1' then return -mult_unsigned(bv1, -bv2); elsif bv1(bv1'left) = '1' and bv2(bv2'left) = '0' then return -mult_unsigned(-bv1, bv2); else return mult_unsigned(-bv1, -bv2); end if; end function "*";end package body bit_vector_signed_arithmetic;
Uso de Pacotes
• work é a biblioteca padrão
• Pode importar todas as definições do pacoteuse work.bit_vector_signed_arithmetic.all;
• Ou apenas umause work.bit_vector_signed_arithmetic.+
top related