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.