Forum: FPGA, VHDL & Co. Berechnungen in VHDL


von Boris (Gast)


Lesenswert?

Hallo zusammen,
ich hoffe hier kann mir jemand ein paar Tips zu generics in VHDL geben. 
(Oder auch einen alternativen Lösungsweg für meine Aufgabe nennen.)
Und zwar habe ich folgendes Problem. Ich habe einen Core geschrieben, 
welcher an einem AXI hängt. Der Core hat zwei Generics. Ein mal den Wert 
des Clock-Takts und ein mal den der Sample-Rate. Mit diesen beiden Werte 
will ich mir mit Hilfe eines Zählers ein enable-Signal erzeugen um Daten 
von einem ADC entgegen zu nehmen. Derzeit hat die CLK eine Frequenz von 
50MHz und die Samplefrequenz ist 600 kSps. Leider schaffe es nicht dass 
die Synthese sich diese Werte selbst errechnet.
Meine Formel lautet:
f(x)=round(x*(CLK/Samplerate)-round(x*(CLK/Samplerate))+CLK/Samplerate
Hier mal ein Auszug aus meinem VHDL-Code und die zugehörige 
Fehlermeldung:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
use IEEE.MATH_REAL.ALL;
5
use std.textio.all;
6
7
entity core_logic is
8
    generic(
9
      C_S_AXI_ACLK_FREQ_HZ : integer := 50_000_000;
10
      sample_rate : integer := 9_600_000
11
      );
12
    port(
13
      clk : in  STD_LOGIC;
14
...
15
architecture Behavioral of core_logic is
16
17
signal sample_en : integer range 0 to 15 := 0;
18
...
19
sample_en_process : process begin
20
   wait until rising_edge(clk);
21
   if sample_en = counter-1 then
22
      sample_en <= 0;
23
    sample_cnt <= sample_cnt +1;
24
   else
25
      if sample_rdy_i = '1' then
26
         sample_en <= 0;
27
      sample_cnt <= 0;
28
      else
29
         sample_en <= sample_en + 1;
30
      end if;
31
   end if;
32
end process;
33
34
counter_process : process begin
35
  wait until rising_edge(clk);
36
  case sample_cnt is
37
    when 0 =>  counter <= (ROUND((C_S_AXI_ACLK_FREQ_HZ/sample_rate)));--5;
38
    when 1 =>  counter <= (ROUND(1*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(1*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
39
    when 2 =>  counter <= (ROUND(2*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(2*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
40
    when 3 =>  counter <= (ROUND(3*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(3*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
41
    when 4 =>  counter <= (ROUND(4*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(4*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
42
    when 5 =>  counter <= (ROUND(5*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(5*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
43
    when 6 =>  counter <= (ROUND(6*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(6*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
44
    when 7 =>  counter <= (ROUND(7*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(7*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
45
    when 8 =>  counter <= (ROUND(8*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(8*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
46
    when 9 =>  counter <= (ROUND(9*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(9*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
47
    when 10 => counter <= (ROUND(10*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(10*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
48
    when 11 => counter <= (ROUND(11*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(11*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
49
    when 12 => counter <= (ROUND(12*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(12*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
50
    when 13 => counter <= (ROUND(13*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(13*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
51
    when 14 => counter <= (ROUND(14*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(14*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
52
    when 15 => counter <= (ROUND(15*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(15*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
53
    when others => counter <= (ROUND(15*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(15*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
54
  end case;
55
end process;
56
...
57
data_sampling_process : process begin
58
   wait until rising_edge(clk) and sample_en = 0;
59
   ch1_out_i <= ch1_out_i(14 downto 0) & channel1_i;
60
   ch2_out_i <= ch2_out_i(14 downto 0) & channel2_i;
61
end process;

von Boris (Gast)


Lesenswert?

Boris schrieb:
> counter_process : process begin
>   wait until rising_edge(clk);
>   case sample_cnt is
>     when 0 =>  counter <= (ROUND((C_S_AXI_ACLK_FREQ_HZ/sample_rate)));--5;
>     when 1 =>  counter <= 
(ROUND(1*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(1*(C_S_AXI_ACLK_FREQ_H 
Z/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));

Ich bin leider statt auf Vorschau auf senden bekommen und konnte so die 
letzte Änderung im VHDL nicht mehr einfügen.
Der zitierte Code-Schnippsel lautet derzeit so:
1
counter_process : process begin
2
  wait until rising_edge(clk); -- enable wird hier fehlen!!!
3
  case sample_cnt is
4
    when 0 =>  counter <= integer(ROUND((C_S_AXI_ACLK_FREQ_HZ/sample_rate)));
5
    when 1 =>  counter <= integer(ROUND(1*(C_S_AXI_ACLK_FREQ_HZ/sample_rate)-ROUND(1*(C_S_AXI_ACLK_FREQ_HZ/sample_rate))+(C_S_AXI_ACLK_FREQ_HZ/sample_rate)));

Und die Fehlermeldung sieht dann so aus:
1
ERROR:HDLCompiler:1731 - "/home/CORRAIL/metka/tmp/sensor_head_simulation/core_logic.vhd" Line 122: found '0' definitions of operator "/", cannot determine exact overloaded matching definition for "/"
2
ERROR:HDLCompiler:1731 - "/home/CORRAIL/metka/tmp/sensor_head_simulation/core_logic.vhd" Line 123: found '0' definitions of operator "*", cannot determine exact overloaded matching definition for "*"
Ich freue mich schon über euren Input.
Gruß Boris

von jjj (Gast)


Lesenswert?

Hey Boris,

hoffe du liest das noch ...
Round erwartet einen floating Datentyp.... Du gibts ihm Integer/Integer= 
abgehackter Integer

Probier mal das ...


1
constant C_S_AXI_ACLK_FREQ_HZ : integer := 50_000_000;
2
constant sample_rate : integer := 9_600_000;
3
constant test : integer := integer((ROUND(real(C_S_AXI_ACLK_FREQ_HZ)/real(sample_rate))));

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.