Hallo, ich will meine E-Gitarre mit Hilfe meines FPGAs stimmen. Ich hab mir das so vorgestellt: Ich erzeuge einen 1Hz Takt. Bei jedem Takt wird der Frequenzzähler, der auf die steigende Flanke des Tons reagieren soll, in einen Puffer geschrieben und danach auf 0 gesetzt. Dann wird der Puffer an die 7-Segment Anzeige ausgegeben und zwar so lange, bis der nächste 1Hz Takt kommt usw. Der Frequenzzähler zählt demzufolge die steigenden Flanken des Tons für eine Sekunde lang. D.h. nach dieser Sekunde steht die genaue Frequenz im Zähler. Die Aktualisierung der 7-Segment Anzeige mache ich extra nur jede Sekunde, da man, wenn man es schneller macht, womöglich nur noch Segmentsalat sieht....und ich muss keine Umrechnungen der Frequenz machen, da ich ja genau eine Sekunde lang mitzähle. Nun zum eigentlichen Problem: Signal freq cannot be synthesized, bad synchronous description. Ich weiß, dass dieses Thema schon einige Male hier im Forum war, doch ich wurde nicht schlau aus den Threads, da ich Anfänger bin und die Ursache dieser Fehlermeldung nicht finde. Im Anhang ist mein VHDL-Code. Der Frequenzzähler soll ja jede Sekunde auf 0 gesetzt werden, damit er wieder von vorne beginnt - klingt doch logisch oder??? ;) Und genau da liegt das Problem. Wenn ich den Zähler bei jedem 1Hz Takt resetten will, erscheint diese Meldung. Genauso ist es, wenn ich den reset Taster abfrage, um alles zu resetten. Auch dort erscheint die Meldung dann. Das Signal tone_in ist natürlich asynchron und wird später übrigens an einem Schmitt-Trigger an der Gitarre hängen, damit ich ein Rechtecksignal bekomme. Nun meine Fragen: Was mache ich falsch, dass diese Meldung erscheint? Wie kann man das umgehen? Wie könnte man dieses Projekt besser machen, also weniger Ressourcen verbrauchen, eventuell eine höhere max. Taktfrequenz des FPGAs erreichen... Mir geht es hauptsächlich um die erste Frage. Trotzdem ist mir die zweite Frage auch wichtig, damit ich lerne, wie man so etwas besser machen kann. Danke schon mal im Voraus! Gruß Daniel!
ich würde sagen das dein reset falsch ist? unzwar ist er bei dir so: if rising_edge(clk) then if reset then end if; --und hier kommt dein restlicher code. man sollte es besser so machen. ================================ if rising_edge(clk) then if reset then else --und hier kommt dein restlicher code. end if; end if; unzwar passiertes das du ihm zum gleichen zeitpunkt resetest, ihm aber auch weiter zählen lässt hab den code auch geändert. probiers mal. mfg
Danke john-eric. Ich werds gleich probieren. Wenn das schon alles an Fehlern war ist ja super :) Gruß Daniel.
...Habs probiert...ist ja auch logisch: die Fehlermeldung erscheint immer noch und ich weiß nicht an was es liegt :(
das kommt daher das du mit 2 tackten arbeitest. ist mir dafor nicht aufgefallen. ich schreibs mal um. stelle es nachher rein. mfg
am besten ist du hälst alles synchron zum tackt signal. durch die beiden signale tone_in1 und tone_in2 kannste die flanke von tone_in erkennen. hoffe mal dein clk ist um einiges höher als tone_in. mfg john-eric
Danke john-eric. Ich hoffe mal, dass es nun funktioniert. Ich probiers gleich mal aus. Mein Clock ist 50MHz ...auf dem Xilinx Spartan3 Starter-Kit. Ich meld mich nochmal... Daniel
@ John-eric Vielen Dank für deine Hilfe. Ich habe tone_in im Moment an einem Taster hängen, sodass ich an diesem sozusagen eine Test-frequenz erzeugen kann...und ich muss sagen: Es funktioniert ausgezeichnet. Aber ich verstehe nicht, warum tone_in2 Low sein kann, während tone_in1 High ist. Kannst du oder jemand anders mich bitte aufklären, wie das vor sich geht? Laut meinen Überlegungen müsste tone_in1 und tone_in2 im selben Takt den Wert von tone_in annehmen. Aber dann würde es ja gar nicht funktionieren.....doch es funktioniert. Also muss an meiner Überlegung was falsch sein.....aber was??? Wie geht der FPGA an den folgenden Abschnitt ran??? if rising_edge(clock) then tone_in1 <= tone_in; tone_in2 <= tone_in1; Kann mir das bitte noch jemand erklären?? Dann wäre ich voll zufrieden. Danke. Gruß Daniel!
Hallo Daniel, das läuft folgendermaßen: Irgendwann ändert sich tone_in. Mit der nächsten steigenden clock-Flanke (rising_edge(clock)) wird der Wert von tone_in nach tone_in1 übernommen. Bei der selben Flanke wird der alte Wert von tone_in1 nach tone_in2 übernommen, d.h. tone_in2 behält erstmal seinen alten Wert. Erst bei der zweiten steigenden clock-Flanke ändert sich auch tone_in_2. Zur Veranschaulichung: _ _ _ _ clock _| |_| |_| |_| |_| |_| |_ _______ tone_in ______| |________ _____ tone_in1 _________| |_______ _____ tone_in2 _____________| |___ Gruß Ines PS: Wie willst Du eigentlich aus dem Gitarrenton Dein Signal tone_in generieren?
@Ines Vielen Dank für die Erklärung. Ich habs soweit verstanden! :) <"Wie willst Du eigentlich aus dem Gitarrenton Dein Signal tone_in generieren?"> Ganz einfach... ich schau mal am Oszi was für ein Signal der LineOut des Verstärkers so hergibt... da dieses Signal dann wahrscheinlich im Millivoltbereich (ich schätze 200 mV) liegt muss ich es erst noch verstärken...mit nem Spannungsteiler nen Transi vorspannen und Signal draufgeben, wahrscheinlich mit Open Collector und Pullup. Die Invertierung dabei spielt ja keine Rolle...sodass ich dann auf 3,3V komme, damit der FPGA was damit anfangen kann. Dann noch über einen Schmitt-Trigger, damits ein Rechteck gibt...und dann auf den FPGA. Danke nochmal für eure Hilfe. Gruß Daniel!
@ Daniel Danke für die Antwort! Ich habe nämlich ein ähnliches Projekt in Plannung wie Du - nur für akkustische Gitarren :-) Ines
@Daniel: >Kannst du oder jemand anders mich bitte aufklären, wie das vor sich >geht? Laut meinen Überlegungen müsste tone_in1 und tone_in2 im selben >Takt den Wert von tone_in annehmen. Aber dann würde es ja gar nicht >funktionieren.....doch es funktioniert. Also muss an meiner >Überlegung was falsch sein.....aber was??? Ja ist es, ging mir am Anfang ebenso. Es sind parallele Prozesse die du mit VHDL beschreibst. Also eben nicht so wie du es vom normalen Programmieren her gewohnt bist. Ich für mich habe mich an folgende "Denkweise" gewöhnt: Betrachte ALLES vom Standpunkt "was ist Input" und "was ist Output". Ein Signal hat sozusagen einen "Input" und einen "Output", Beides sind sozusagen ZWEI Variablen zu einem Signal. Im VHDL siehtst du nun nur zwei relevante Informationen als Source. Nämlich wie fießen die Daten zu einem Zeitpunkt in einen Input eines Signales oder aus welchen Output eines Signales werden Daten geholt. Beispiel: process(Clock) begin if rising_edge(Clock) then Inp1 <= Daten; Inp2 <= Inp1; end if; end process; Inp1.Input <= Daten; Inp2.Input <= Inp1.Output. So: Inp1.Input und Inp2.Output sind zwei UNTERSCHIEDLICHE "Variablen" mit unterchiedlichem Inhalt zum Zeitpunkt der steigenden Flanke von Clock. Wenn du Inp1.Input schreibst so änderst du eben NICHT den Inhalt von Inp1.Output mit. DAS ist nämlich exakt das was die steigebnde Flanke zu diesem Zeitpunkt macht. Du hast also im Grunde eben KEINE Einfluß darauf wie von Inp1.Input zu Inp2.Output die Daten fließen, denn dies ist exakt das was die erzeugte Hardware als Clock Einang eines FF's durchführt. Ich weis, eventuell eine falsche Sicht der Dinge, aber mir hat sie geholfen zu verstehen warum parallel stattfindene Vorgänge im FGPA zu funktioneren müssen. Gruß Hagen
@Ines Ich hoffe, ich kann das Teil bald bauen. Dann berichte ich nochmal darüber. @Hagen Vielen Dank für die Erklärung. Ich wollte sowieso grad nochmal fragen, wie so ein Prozess abgearbeitet wird...aber du hast das ja schon beantwortet. Ich werd mir das ein paar mal durchlesen, bis es "klick" macht. :) Danke nochmal an alle. Gruß Daniel!
Vielleicht nochmal elektronischer betrachtet. Du hast eine Speicherzelle=FF. In der steht zum Zeitpunkt der steigenden Flanke eine 1 drinnen. Wenn du dieses FF nun liest im Prozess, also Input2 <= Input1, du liest also Input1 dann bekommst du natürlich den aktuellen Inhalt == 1 geliefert. Schreibst du nun in Input1 <= Daten rein, zb. eine 0, dann wird dies eben mit der steigenden Flanke erfolgen, als Takteingang für dieses FF. Somit kann die "0" beim lesen aus dem FF zum gleichen Zeitpunkt -> steigende Flanke, noch garnicht im FF gespeichert sein. So betrachtet man dieses FF also mit zwei Variablen -> FF.Input und FF.Outout und die steigende Flanke als den Zeitpunkt in dem das FF gelesen, geschrieben und über den Takteingang auch übernommen wird dann passiert folgendes: FF hat Inhalt 1. FF.Input <= 0; FF.Output == 1; steigende Flanke des Taktes am FF, setzt FF.Output <= FF.Input. Das alles passiert parallel aber eben NICHT metastabil, exakt zum Zeitpunkt der steigenden Flanke in deinem Prozess. Im Grunde arbeitest du in VHDL nicht mit Zuständen, sondern du beschreibst ein Verhalten was passieren soll. Mann, ich bin selber ja noch Anfänger, und diesen wichtigen Sachverhalt, der wohl für Profis absolut trivial erscheint, zu erklären fällt doch recht schwer. Gruß Hagen
interessant, wie sich die "Softis" versuchen, die Hardware zu erklären 8-)) (Glück gehabt, bei mir kam die Hardware zuerst, dann die Geschichte mit der Software...)
@FPGA-User, wie sähe eine bessere Erklärung aus. Wie es rein HW-technisch funktioniert ist mir durchaus bewusst, nur würde so eine Standard-Erklärung aus dem Lehrbuch, einem Software-Programmierer die Geschichte einfacher erklärbar machen ? Mir haben die vielen Dokus nicht so recht geholfen. Aber mein "eigener Denkansatz" hilft mir dabei immer wieder bei jeder kleinen VHDL Sourcezeile es im Grunde richtiger zu sehen. Gruß Hagen
ich persönlich stelle mir das als master slave flipflop vor. mfg
@Hagen habe keine bessere Erklärung, das Verhalten der Hardware hat sich bei mir tief eingeprägt, als ich vor vielen Jahren meine ersten Schaltungen mit den 7400 usw. gebaut habe. Bei mir war das Problem eher, dass ich mir nicht vorstellen konnte, sowas mit VHDL zu beschreiben.
> Bei mir war das Problem eher, dass ich mir nicht > vorstellen konnte, sowas mit VHDL zu beschreiben. geht mir genauso :-) Allerdings hat trotz der (Syntax-/Grammatik-) Probleme, die zumindest ich u.a. mit VHDL habe, VHDL eine gewissene Eleganz bei der Hardwarebeschreibung - jetzt verstehe ich, warum viele vom Schematics Entwurf abraten und bin froh, diesen Rat gefolgt zu sein. Viele Grüße Olaf
Hmmm, das is ja mal ne komplizierte Sache. Wie gesagt, ich bin Anfänger...hab seit ca. 2 Monaten ein Xilinx Spartan3 Starter Kit und probier halt ab und zu mal was damit aus, um den FPGA und VHDL kennenzulernen. Hinzu kommt, dass ich das alles als Hobby mache. Und mit Hardware hatte ich bis jetzt auch noch nicht sehr viel am Hut...mit Software genauso wenig. Hab mir vor ca. einem halben Jahr nen Mikrocontroller zugelegt und Assembler programmiert. Dann habe ich Wind von VHDL bekommen und hab mir gesagt, dass so ein FPGA Board einfach her muss. Und nun habe ich eben die typischen VHDL Anfängerprobleme.... und die Parallelität und die Prozeasse sind ja nicht wirklich einfach. Naja, ich werds mir demnächst nochmal so richtig zu Gemüte führen. Danke nochmal für eure Hilfe. Weitere Anregungen sind herzlichst willkommen. Gruß Daniel!
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.