Forum: FPGA, VHDL & Co. Berechnung einer Frequenz aus constant-std_logic_vector


von Alex O. (alex_92)


Lesenswert?

hallo,
da ich nun endlich den Einstieg in VHDL getätigt habe, arbeite ich 
gerade viel mit Beispielcodes. Und bei einem habe ich so meine Probleme.
Ich kann den Code zwar soweit nachvollziehen habe aber ein eher 
nebensächliches Problem.

Hier mal die vermutlich wichtigsten Zeilen.
1
signal clk_div    :  std_logic_vector(12 downto  0);
2
constant duo    :  std_logic_vector(12 downto  0) := "0111011101110"; -- 654
1
if (clk_div /= e2) then
2
  clk_div <= clk_div + "0000000000001";
3
else
4
  clk_div <= "0000000000000";
5
  out_bit <= not out_bit;
6
end if;

Sinn der Programms ist es am out_bit einen Buzzer mit einer Frequenz, 
welche hauptsächlich durch die Konstante bestimmt wird, zu betreiben.

Das Programm funktioniert auch soweit, nur möchte ich nun die Frequenz 
am Buzzer bestimmen, um den Code gegebenenfalls zu erweitern.
Die Frequenz, mit der der FPGA betrieben wird, ist 50MHz, die wird aber 
im Code (nicht im Ausschnitt enthalten) durch 10 geteilt.

Mein Ansatz:
der zweite Code-Abschnitt wird mit einer Frequenz von 5MHz aufgerufen.
Die Frequenz des LSB wäre dann 5MHz bzw. dessen λ = 1/5MHz.
"0111011101110" ist im Dezimalsystem 1911
Nun müsste ein Zustand die λ = 1911 x 1/5MHz haben.
Da es zwei Zustände (ein & aus) sind => λ = 2 x 1911 x 1/5MHz = 
3822/5MHz
Die Frequenz am Ausgang wäre damit f = 1/λ = 5MHz/3822 = 654Hz

Jedoch bin ich mir bei der Rechnung nicht sicher.
Grund dafür ist, das es mehrere Konstanten(mit chinesischer Bezeichnung 
(duo, lai, mi, fa, suo, la, xi, duo1)) gibt.
Aufgrund der Namen gehe ich davon aus, das die ersten 7 einer 
gemeinsamen Ton-Gruppe angehören und der 8. der nächst Höheren.
Nach meinen Berechnungen und einer Liste aus dem i-net passt das aber 
nicht.

Kann mir da jemand helfen?

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Alex O. schrieb:
> Hier mal die vermutlich wichtigsten Zeilen.
Dieser Code ist schon auf den ersten Blick der eines Anfängers und 
eigentlich unglaublicher Krampf. Man verwendet hier besser einen 
geeigneten Datentyp und lässt den Synthesizer rechnen. So wie ich hier 
bei der Baudrate:
http://www.lothar-miller.de/s9y/archives/48-RS232.html

> Mein Ansatz: ...
Ist richtig, aber der Umweg über die Pulsdauer ist umständlich. Rechne 
einfach so:
5000000Hz/1911/2 = 654Hz

> Nach meinen Berechnungen
Welchen?
> und einer Liste aus dem i-net
Welcher?
> passt das aber nicht.
Warum?


> der zweite Code-Abschnitt wird mit einer Frequenz von 5MHz aufgerufen.
Das ist seltsam. Wie wird diese "Aufrufefrequenz" erzeugt?
BTW: der "Code" wird nicht "aufgerufen", sondern die Beschreibung in 
Hardware umgesetzt.

: Bearbeitet durch Moderator
von Alex O. (alex_92)


Lesenswert?

hallo,
hier mal alle Konstanten mit den errechneten Werten und Ton als 
Kommentare dahinter.
1
   CONSTANT  duo   :  std_logic_vector(12 DOWNTO 0) :="0111011101110"; -- 654 e2
2
   CONSTANT  lai  :  std_logic_vector(12 DOWNTO 0) := "0110101001101"; -- 734 fis2
3
   CONSTANT  mi   :  std_logic_vector(12 DOWNTO 0) := "0101111011010"; -- 824 gis2
4
   CONSTANT  fa    :  std_logic_vector(12 DOWNTO 0) := "0101100110001"; -- 873 a2
5
   CONSTANT  suo   :  std_logic_vector(12 DOWNTO 0) := "0100111110111"; -- 980 h2
6
   CONSTANT  la    :  std_logic_vector(12 DOWNTO 0) := "0100011100001"; -- 1100 cis3
7
   CONSTANT  xi    :  std_logic_vector(12 DOWNTO 0) := "0011111101000"; -- 1235 dis3 
8
   CONSTANT  duo1   :  std_logic_vector(12 DOWNTO 0) := "0011101110111"; -- 1308 e3

Die Liste ist bei Wikipedia unter "Frequenzen der gleichstufigen 
Stimmung" zu finden.
Hier passen erstens die Werte nicht genau, wo ich nun aber auch nicht 
weiß, wie präzise man sich diesen Werten annähern kann und die 
Ton-Gruppen sind auch anders. Nach der Liste sind die ersten 5 in einer 
Gruppe und die letzten drei in der darauf Folgenden. Einige Töne wären 
auch Zwischentöne wie z.B. (fis, gis, cis, dis).

zu den 5MHz:
1
signal clk_div10  :  std_logic_vector(3  downto  0);
2
process (rst, clk)
3
begin
4
  if (not rst = '1') then
5
      clk_div10 <= "0000";
6
  elsif (clk'event and clk= '1') then
7
    if (clk_div10 /= "1001") then
8
      clk_div10 <= clk_div10 + "0001";
9
    else
10
      clk_div10 <= "0000";
11
    end if;
12
  end  if;
13
end process;

Und der zweite Code-Abschnitt hat noch eine if-Abfrage voraus.

von Achim S. (Gast)


Lesenswert?

der Rechenweg passt, aber der Ausgangswert ist imho einen Faktor 2 
daneben:
"0111011101110" entspricht nicht 1911 sondern 3822. Oder wird bei der 
Zuweisung der Konstanten nach e2 das unterste Bit abgeschnitten?

von Achim S. (Gast)


Lesenswert?

und noch eine kleine Korrektur hinterher: wenn du die erzeugte Frequenz 
genau bestimmen willst, dann musst du durch den Wert der Konstante+1 
dividieren (denn div_cnt läuft von 0 bis zum Wert der Konstante).

Also: 5MHz/(3822+1)/2=653,937

Der Unterschied zur Rechnung oben macht sich natürlich nur in den 
Nachkommastellen bemerkbar.

von Alex O. (alex_92)


Lesenswert?

Achim S. schrieb:
> "0111011101110" entspricht nicht 1911 sondern 3822

Sie haben recht. Dann habe ich mich wohl verschrieben, denn an der 
Rechnung bzw. der Ergebnisse ändert sich nichts.

Aber leider bin ich bisher noch nicht schlauer geworden.

von Alex O. (alex_92)


Lesenswert?

Hallo,
da das Beispiel ja chinesischer Abstammung ist, wäre es ja möglich, das 
die dort eine andere Tonleiter verwenden.
Ich habe ein wenig gesucht, konnte aber Nirgends die hier verwendeten 
Bezeichnungen finden.
Aber über den Konstanten steht folgendes Kommentar:
"¸÷¸öÒôµ÷µÄ·ÖƵϵÊý"

Ich vermute mal, dass das verendete ASCII-Format leicht von meinem 
abweicht.
Kennt jemand ne Methode dies leserlich zu machen?
Könnte evt. zur Lösung beitragen, falls da genaueres steht.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Alex O. schrieb:
> zu den 5MHz: ...
So wird kein Takt erzeugt. Das Design ist Murks und gehört in die Tonne.
Von den ungeeigneten std_logic Vektoren abgesehen:
Warum sollte ich eine für eine exakte Frequenzerzeugung erträglich hohe 
Taktfrequenz erst mal um 10 herunter teilen?

Ich halte es für sehr wahrschrinlich, dass ein Chinese für seine 
Tonleiter keine in Europa gängige Skala nimmt...

Alex O. schrieb:
> Aber über den Konstanten steht folgendes Kommentar:
> "¸÷¸öÒôµ÷µÄ·ÖƵϵÊý"
Das wird sich wahrscheinlich nicht sehr ändern, auch wenn du den 
richtigen Schriftsatz verwendest. Oder meinst du, ais den resultierenden 
chinesischen Schriftzeichen etwas ablesen zu können?

Warum simulierst du dieses Design nicht einfach? Dann findest du 
schnell heraus, welche Frequenzen verwendet werden...

: Bearbeitet durch Moderator
von Alex O. (alex_92)


Lesenswert?

Lothar Miller schrieb:
> Und wer sagt eigentlich, dass ein Chinese für seine Tonleiter eine in
> Europa gängige Skala nimmt?

Davon war ich anfangs ausgegangen.
Aber auch wenn ich nichts genaueres finden konnte, gehe ich mal davon 
aus, dass das nicht so ist.

Ich habe etwas davon gelesen, dass die so genannte Vierteltöne haben, 
welche wir nicht haben, was erklären würde, warum die errechneten Werte 
nicht ganz zu den Tönen in der Tabelle von Wikipedia passen.

Wenn wir mal davon ausgehen, dass es daran liegt, hätte sich mein 
Anliegen soweit geklärt. Nun kann ich Rückwärts-rechnen und die 
Konstanten unseren Tönen anpassen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Alex O. schrieb:
> Nun kann ich Rückwärts-rechnen und die Konstanten unseren Tönen
> anpassen.
Wenn du schon dabei bist, dieses lausige Design deinen Wünschen 
anzupassen: verwende einen Integer als Zähler. Dann kannst du einfach 
lesbare Zahlen hinschreiben und musst nicht irgendwelche Bitmuster 
ausknobeln...

von Alex O. (alex_92)


Angehängte Dateien:

Lesenswert?

Lothar Miller schrieb:
> Oder meinst du, ais den resultierenden
> chinesischen Schriftzeichen etwas ablesen zu können?

Sobald ich die chinesischen Schriftzeichen habe, könnte ich einen 
Übersetzer verwenden.

Lothar Miller schrieb:
> Warum simulierst du dieses Design nicht einfach? Dann findest du
> schnell heraus, welche Frequenzen verwendet werden...

Soweit bin ich leider noch nicht.
Ich habe zwar das Tutorial von  Altera verwendet aber aufgrund meines 
veralteten Cyclone I muss ich Quartus II 11.0sp1 verenden, weil neuere 
diesen nicht unterstützen. Und im Tutorial zum Abschnitt "Simulieren" 
sind Schaltflächen und Abbildung, die von meiner Version abweichen.
Das Simulieren muss ich bei Gelegenheit nachholen.

Lothar Miller schrieb:
> Wenn du schon dabei bist, dieses lausige Design deinen Wünschen
> anzupassen: verwende einen Integer als Zähler.

Habe es so gemacht, wie Sie es wünschen.
Ich entnehme Ihren Kommentaren, dass Sie Profi sind, was VHDL betrifft.
Ich habe im Anhang die überarbeitete Version angefügt und würde mich 
freuen, wenn Sie kurz hineinschauen würden und mir Ratschläge zum Thema 
Code/Design-Optimierung geben könnten, damit ich zukünftig keinen 
"krampf" Code mehr produziere oder verwende.

Und eine Frage nebenbei.
Zu Übungszwecken möchte ich den Code so erweitern, das ich per RS232 die 
Töne zum FPGA sende.
Vermutlich würde sich der von Ihnen gepostete link gut dafür eignen.
Nun ist die Frage, wie ich das zusammen bringen soll?
Als Anfänger würde ich nun beide Codes zerpflücken und in eine 
gemeinsame Entity & Architecture zusammenfügen.
Jedoch würde es mich wundern, wenn dies nicht auch professioneller 
ginge.
Über Ansätze würde ich mich sehr freuen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Vorneweg: wenn ich dich ungefragt duze, dann darfst du das auch.

Zu deiner Beschreibung:
constant f2  :  integer range 0 to 8191 := 3579;
Eine Konstante ist konstant und braucht deshalb keinen range.

Du kannst meine serielle Schnittstelle als Komponente in dein Design 
einfügen/instantiieren. Sieh dich einfach auf meiner HP um, dort sind 
ein paar Beispiele, wie eine component verwendet wird.

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.