Forum: FPGA, VHDL & Co. VHDL: Funktionsaufruf mit Parametern


von Full W. (realjey)


Lesenswert?

Hallo Forum,

ich habe eine Funktion freqdiv.vhd, welche mir als Frequenzteiler dient. 
Diese Funktion möchte ich nun aufrufen und als Parameter das 
Teilerverhältnis übergeben. Ausserdem möchte ich die Funktion mehrmals 
Aufrufen können und als Rückgabgewert jeweils die geteilte CLK in 
verschiedenen Signalen Q0, Q1, Q2 speichern.

Meine topModule sieht bisher so aus:
1
entity topModule_19 is
2
Port(  CLK  : in  STD_LOGIC; --32MHz
3
       Reset : in std_logic:='0';
4
       MSP  : out STD_LOGIC;
5
       DATA : in std_logic_vector(7 downto 0);
6
    
7
       Test2: out std_logic;
8
       Test3: out std_logic;
9
       Test1: out std_logic:='0'
10
);
11
end topModule_19;
12
13
architecture Behavioral of topModule_19 is
14
  
15
  signal Q0: std_logic; --Signal: geteilte Frequenz-> n=2->Q0=16MHz
16
  signal Q1: std_logic; --Signal: geteilte Frequenz-> n=4->Q1=8MHz
17
  signal Q2: std_logic; --Signal: geteilte Frequenz-> n=8->Q2=4MHz
18
19
begin
20
21
--Instanzierung freqdiv.vhd
22
freqdiv_inst : entity work.freqdiv
23
port map (
24
    CLK      => CLK,
25
    freq_d   => Q0   
26
);

Die dazugehörige freqdiv-Instanz:

....
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity freqdiv is
6
generic (div_n : integer := 8 ); --Teilerverhältnis (fix)
7
    Port ( CLK : in  STD_LOGIC;
8
           freq_d : out  STD_LOGIC);
9
end freqdiv;
10
11
architecture Behavioral of freqdiv is
12
13
begin
14
15
freq_divider: process 
16
variable Z : integer range 0 to div_n-1; 
17
begin
18
wait until rising_edge(CLK); 
19
  if (Z < (div_n-1)) then Z := Z+1;
20
    else Z := 0; end if;
21
  if (Z = 0) then freq_d <= '1'; end if;
22
  if (Z = div_n/2) then freq_d <= '0'; end if;
23
end process freq_divider;
24
25
end Behavioral;

Das funktioniert auch soweit, allerdings kann ich diese Instanz nicht 
mehrmalig aufrufen, da freq_d nur einmal deklariert sein darf in 
topModule.
Desweiteren weiss ich nicht wie ich das generic: (div_n : integer := 8 
); als Parameter deklariere, damit ich bei Aufruf der Funktion (aus 
topModule herraus) das Teilerverältnis mit übergeben kann.

Ziel ist es also wie in C++. freq_div.vhd als Funktion aufrufen zu 
können, mit einem Parameter (div_n = Teilerverhältnis) und als 
Rückgabewert die geilte Frequenz in verschiedenen Signalen speichern 
kann.

von franke (Gast)


Lesenswert?

So denkt kein VHDL Entwickler...

Nimm einen 3-bit Zähler...
fertig.

Gruß

von Full W. (realjey)


Lesenswert?

bin auch keiner ;) bzw. fang ich gerade erst an...

was meinst du mit 3bit-Zähler?

von Klaus F. (kfalser)


Lesenswert?

full well schrieb:
> Desweiteren weiss ich nicht wie ich das generic: (div_n : integer := 8
> ); als Parameter deklariere, damit ich bei Aufruf der Funktion (aus
> topModule herraus) das Teilerverältnis mit übergeben kann.

Zuallererst beachte bitte die korrekten Ausdrücke:
freqdiv ist KEINE Funktion, sondern eine Entity.
Sie wird auch nicht aufgerufen sondern instantiiert.

Du musst freqdiv 3 x instantiieren, mit unterschiedlichen Parametern.
Das heißt, es werden 3 verschiedene Frequenzteiler.
1
--Instanzierung freqdiv.vhd mit Teiler 50
2
freqdiv_inst : entity work.freqdiv
3
generic map ( div_ n => 50)
4
port map (
5
    CLK      => CLK,
6
    freq_d   => Q0   
7
);
8
9
--Instanzierung freqdiv.vhd mit Teiler 100
10
freqdiv_inst : entity work.freqdiv
11
generic map ( div_ n => 100)
12
port map (
13
    CLK      => CLK,
14
    freq_d   => Q1   
15
);

von franke (Gast)


Lesenswert?

so in etwa...

signal cnt : std_logic_vector(2 downto 0);

process(clk, reset)
begin
if (  reset = '1' ) then
  cnt <= "000";
elsif ( clk'event and clk='1' ) then
 cnt <= cnt + '1' ;
end if;
end prcoess;

q0 <= cnt(0);
q1 <= cnt(1);
q2 <= cnt(2);

von Full W. (realjey)


Lesenswert?

Hallo Klaus,

danke ich glaube das ist was ich suche!

allerdings bekomme ich bei
1
generic map ( div_ n => 50)
2
generic map ( div_ n => 100)

jeweils einen Fehler: ERROR:HDLCompiler:806.
Line 151: Syntax error near "=>".

Wie muss ich div_n denn jetzt in meiner freqdiv-Entity deklarieren?
1
generic (div_n : integer := 8 );

kann ja so nicht mehr stimmen oder?

Danke für RE!

von Klaus F. (kfalser)


Lesenswert?

full well schrieb:
> Wie muss ich div_n denn jetzt in meiner freqdiv-Entity deklarieren?
> generic (div_n : integer := 8 );

Genau so.
Die Zuweisung := 8 ist nur eine Defaultwert für div_n, solange nichts 
anderes angegben wird.
Durch das generic map wird div_n für diese Instanz überschrieben und 
dieser Frequenzteiler arbeitet nicht mit 8 sondern mit dem angegebenen 
Wert, z.B. 50.

> allerdings bekomme ich bei
> generic map ( div_ n => 50)
> generic map ( div_ n => 100)
>
> jeweils einen Fehler: ERROR:HDLCompiler:806.
> Line 151: Syntax error near "=>"

Leerzeichen zwischen div_ und n ?

von Full W. (realjey)


Lesenswert?

habs, war nur ein leerzeichen zwischen div und n...

funzt wie es soll..Danke!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.