VHDL Funktionen und Prozeduren

In folgendem Code ist ein Beispiel für eine Funktion und eine Prozedur in VHDL dargestellt. Gleichzeitig wird das image Attribut für die Ausgabe im Simulator logfile demonstriert. Die Prozedur enthält wait statements und ist deshalb nicht synthetisierbar. In diesem Beispiel wird sie zur Erzeugung einer Sequenz für ein Signal eingesetzt.

library ieee;
use ieee.std_logic_1164.all;
 
-- Example for function and procedure usage
-- and the usage of the image attribute for reports
 
entity func_example is 
end; 
 
architecture beh of func_example is
 
-- Example for a function
-- Function computes the number of zeros in a std_ulogic_vector
function count_zeros (s : std_ulogic_vector) return integer is
  variable nr_of_zeros : integer := 0; 
begin
  for i in s'range loop
    if s(i) = '0' then
      nr_of_zeros := nr_of_zeros + 1; 
    end if;
  end loop; 
  return nr_of_zeros; 
end function count_zeros;  
 
-- Example for a sequence generator which can be used
-- in a testbench 
-- The parameter can be a signal, constant or variable
-- The mode can be in, out or inout
-- Here it is a signal with mode inout
procedure gen_sequence(signal s : inout std_ulogic_vector) is
begin
  for i in s'range loop
    s(i) <= '0';
  end loop;
  wait for 50 ns;
 
  for i in s'range loop
    s(i) <= '1';
  end loop;    
  wait for 50 ns;
 
  for i in s'range loop
    if i mod 2 = 0 then
      s(i) <= not(s(i)); 
    end if;
  end loop;
  wait for 50 ns;   
end procedure gen_sequence; 
 
signal a : std_ulogic_vector(7 downto 0); 
signal b : std_ulogic_vector(15 downto 0); 
 
begin
 
  -- Simple demonstration for the function call  
  fex_p: process
    constant a : std_ulogic_vector := x"FFFFFFE0"; 
  begin
    -- The image attribute for the integer type converts the integer result of 
    -- the count_zeros function to a string
    -- The & operator concatenates the two strings and this is then reported in the simulator log
    report "Number of Zeros in hex FFFFFFE0 is: " & integer'image(count_zeros(a));
    report "Number of Zeros in bin 01010101 is: " &  integer'image(count_zeros("01010101"));    
    wait; 
  end process fex_p;
 
  -- Sequence generation process
  -- Uses the procedure to produce a timed sequence for signal a and b  
  gen_p : process
  begin
    gen_sequence(a);
    gen_sequence(b);
    gen_sequence(a);
    wait;
  end process gen_p; 
 
  -- This process evaluates the signal a and b and 
  -- reports the number of zeros in the signal
  eval_p : process(a,b)
  begin
    report "Number of Zeros in a is: " & integer'image(count_zeros(a));
    report "Number of Zeros in b is: " & integer'image(count_zeros(b));
  end process eval_p;
 
end; -- architecture
Was passiert in diesem Code?

Die Architektur enthält drei Prozesse. Der eval_p Prozess ist mit einer sensitivity list versehen, d.h. er wird nur gestartet, wenn sich das Signal a oder das Signal b ändert.

Der fex_p Prozess wird zu Beginn der Simulation gestartet, wertet die beiden Funktionsaufrufe aus und gibt das Ergebnis aus. Danach kommt das wait statement. Deshalb endet der Prozess gleich zu Beginn der Simulation, ohne dass Zeit verstreicht.

Der gen_p Prozess ruft dreimal die gen_sequence Prozedur auf, die wait statements enthält. Dort wird jeweils für 50 ns gewartet. Es wird zunächst das Signal a dreimal geändert, dann das Signal b und danach wieder a. Danach kommt das wait statement im Prozess. Die gesamte Simulation endet deshalb nach 450 ns.

Der eval_p Prozess wird jedesmal gestartet, wenn sich a oder b ändert, also alle 50 ns.