Berechnungen in VHDL

Gast #3032609
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;
Gast #3032621
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
Gast #3036806
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))));

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.