Hallo alle zusammen, ich möchte in VHDL gerne eine Tabelle anlegen welche ich mit einem 4MHz Signal abtaste und ausgebe. Meine Idee ist ein 3x 16Bit breite Worte abzuspeichern. Wort 1 (Z1): 1110101011001100 Wort 2 (Z2): 1100110010101111 Wort 3 (Z3): 1010101010101010 Also wie einen Tabelle anlegen. Gesteuert wird die Wortauswahl durch ein 250Khz schnelles Datensignal. Durch Flankenerkennung des Datensignals wird dann Z1, Z2 ausgegeben. Das Datensignal hat an jeder 10ten Stelle eine logische null stehen. Wenn diese kommt wird das Datenwort Z3 ausgegeben. Nun stellen sich mir ein paar fragen. 1.) Wenn ich die Worte im BRAM Speicher bekomme ich dann eine Verzögerung weil die Daten erst bei der nächsten steigenden Flanke zurückgegeben werden? Ich gebe ja die Daten dann mit dem 4MHz Takt aus mithilfe eines Schieberegisters und MUX. Ziel ist ja ein Ausgangssignal zu bekommen in dem die Worte kontinuierlich aneinandergereiht ausgegeben werden. Muss ich die Worte in den BRAM speichern oder gibt es andere Möglichkeiten? 2.) Das einzige ist was ich als Problem ansehe ist wenn mein Datensignal 4x hintereinander eine 0 kommt. Wie kann ich da auf eine Flanke prüfen? Weil 0000 hat keine Flanken. Beste Grüße
:
Bearbeitet durch User
Sawyer M. schrieb: > 2.) Das einzige ist was ich als Problem ansehe ist wenn mein Datensignal > 4x hintereinander eine 0 kommt. Wie kann ich da auf eine Flanke prüfen? > Weil 0000 hat keine Flanken. Richtig: es geht nicht. Und was ist dann das Problem? Wenn das nicht sein darf, dann darf in deinem Datensignal eben nicht so oft eine 0 kommen... > Meine Idee ist ein 3x 16Bit breite Worte abzuspeichern. > Wort 1 (Z1): 1110101011001100 > Wort 2 (Z2): 1100110010101111 > Wort 3 (Z3): 1010101010101010 Sind das statische Werte oder sollen die zur Laufzeit geändert werden? > Also wie einen Tabelle anlegen. Gesteuert wird die Wortauswahl durch ein > 250Khz schnelles Datensignal. Durch Flankenerkennung des Datensignals > wird dann Z1, Z2 ausgegeben. Das Datensignal hat an jeder 10ten Stelle > eine logische null stehen. Wenn diese kommt wird das Datenwort Z3 > ausgegeben. Ich kann nicht erkennen, wie du diese Ausgabe synchronisieren willst. So auf dem Papier kannst du die zehn Stellen ja einfach abzählen, aber wie machst du das in der Praxis? Mit welchem Mechnismus kannst du dort die 10 Bits verfolgen und mitzählen? > 1.) Wenn ich die Worte im BRAM Speicher bekomme ich dann eine > Verzögerung weil die Daten erst bei der nächsten steigenden Flanke > zurückgegeben werden? Der 1 Takt Latency ist doch nicht schlimm, weil du es ja weißt, dass er da ist. Und: welche Flanke denn überhaupt? > Muss ich die Worte in den BRAM speichern oder gibt es andere > Möglichkeiten? Du kannst Distributed RAM nehmen. Oder du kannst die paar Bits direkt in Flipflops speichern und über Kombinatorik ausgeben. > Ziel ist ja ein Ausgangssignal zu bekommen in dem die Worte > kontinuierlich aneinandergereiht ausgegeben werden. Womit wird diese Datenübertragung synchronisiert? Allein über die Zeit wie bei einer seriellen Schnittstelle? > Durch Flankenerkennung des Datensignals wird dann Z1, Z2 ausgegeben. Arbeitest du eigentlich am selben Problem wie Fabian im Beitrag "Select auf fallende und steigende Flanke"? Ich würd dir empfehlen, hier mal das eigentliche Problem zu schildern (woher kommen welche Signale mit welchen Frequenzen, was soll damit gemacht und wie darafu regiert werden?) und nicht nach Lösungen für Detaiprobleme zu fragen, die nur deshalb entstehen, weil der grundlegende Ansatz umständlich ist...
>> Meine Idee ist ein 3x 16Bit breite Worte abzuspeichern. >> Wort 1 (Z1): 1110101011001100 >> Wort 2 (Z2): 1100110010101111 >> Wort 3 (Z3): 1010101010101010 > Sind das statische Werte oder sollen die zur Laufzeit geändert werden? Das sind statische Werte und müssen zur Laufzeit nicht abgeändert werden. >> Also wie einen Tabelle anlegen. Gesteuert wird die Wortauswahl durch ein >> 250Khz schnelles Datensignal. Durch Flankenerkennung des Datensignals >> wird dann Z1, Z2 ausgegeben. Das Datensignal hat an jeder 10ten Stelle >> eine logische null stehen. Wenn diese kommt wird das Datenwort Z3 >> ausgegeben. > Ich kann nicht erkennen, wie du diese Ausgabe synchronisieren willst. So > auf dem Papier kannst du die zehn Stellen ja einfach abzählen, aber wie > machst du das in der Praxis? Mit welchem Mechnismus kannst du dort die > 10 Bits verfolgen und mitzählen? Ja das hätte ich über eine Flankenerkennung gemacht vom Datensignal. Aber wenn mehrere nullen nacheinander kommen geht dies eben nicht. Ich muss mir da nochmals Gedanken machen wie ich das umsetze. >> Muss ich die Worte in den BRAM speichern oder gibt es andere >> Möglichkeiten? > Du kannst Distributed RAM nehmen. Oder du kannst die paar Bits direkt in > Flipflops speichern und über Kombinatorik ausgeben. Im Internet werde ich leider nicht richtig fündig, wie man ein paar wenige Bits in FlipFlips speichert und per Kombinatorik ausgeben. Ich denke mir fehlen die Suchbegriffe. Hättest du mir ein Beispiel oder eine Seite oder ein Suchbegriff? Ich denke In FF speichern ist das beste bei meiner Problematik. Spannend wäre auch in den DRAM. Das wäre dann wie eine LUT, oder? >> Ziel ist ja ein Ausgangssignal zu bekommen in dem die Worte >> kontinuierlich aneinandergereiht ausgegeben werden. > Womit wird diese Datenübertragung synchronisiert? Allein über die Zeit > wie bei einer seriellen Schnittstelle? Verstehe die Frage nicht genau, Ich habe ja einen Grundtakt von meinem FPGA von 100MHz. Das Datensignal synchronisiere ich damit. Verstehe ich das gerade falsch? >> Durch Flankenerkennung des Datensignals wird dann Z1, Z2 ausgegeben. > Arbeitest du eigentlich am selben Problem wie Fabian im > Beitrag "Select auf fallende und steigende Flanke"? Nicht das ich wüsste aber es hört sich ähnlich an. > Ich würd dir empfehlen, hier mal das eigentliche Problem zu schildern > (woher kommen welche Signale mit welchen Frequenzen, was soll damit > gemacht und wie darafu regiert werden?) und nicht nach Lösungen für > Detaiprobleme zu fragen, die nur deshalb entstehen, weil der > grundlegende Ansatz umständlich ist... Das Datensignal kommt von einen AD-Wandler vom FPGA selbst. Deshalb ist dieses schon auf den Takt synchron. Dieses Datensignal möchte ich wie oben beschrieben digital modulieren. Die Bits geben ich dann mit dem 4MHz Takt aus. Also Clocktakt_1 -> Bit 1, Clocktakt_2 -> Bit 2, usw. bis ich alle 16Bits (zum Beispiel Z1) nacheinander ausgegeben habe auf ein Ausgangssignal Out. Direkt anschließend kommt vom Datensignal die nächste Flanke an der ich erkenne ob Z1 oder Z2 ausgegeben wird und reihe an das Ausgangssignal Out die nächsten 16Bits an. So entsteht mir ein kontinuierliches Ausgangssignal Out mit meiner aneinandergereihten 16Bit Wörtern. Viele Grüße
:
Bearbeitet durch User
Sawyer M. schrieb: > Das sind statische Werte und müssen zur Laufzeit nicht abgeändert > werden. Dann definiere einfach einen Vektor und gib den über ein Schieberegister oder einen Multiplexer aus:
1 | constant Wort1 : std_logic_vecotr(15 downto 0) := "1110101011001100"; |
2 | constant Wort1 : std_logic_vecotr(15 downto 0) := "1100110010101111"; |
3 | constant Wort1 : std_logic_vecotr(15 downto 0) := "1010101010101010"; |
Und wie der Synthesizer das umsetzt ist dir dabei erst mal völlig egal... > Das Datensignal kommt von einen AD-Wandler vom FPGA selbst. Ein AD-Wandler im FPGA? Oder einem Wandler, der an das FPGA angeschlossen ist und ausgelesen werden soll? > Deshalb ist dieses schon auf den Takt synchron. Dann ist das Einlesen doch simpel, weil die Daten ja mit diesme Takt eingelesen werden können. Aber welchen Takt meinst du denn überhaupt? Den 100MHz-Takt? Oder einen anderen, der mit den 250kHz synchron ist? > Direkt anschließend kommt vom Datensignal die nächste Flanke an der ich > erkenne ob Z1 oder Z2 ausgegeben wird Wie kannst du an einer Flanke erkennen, welches Signal ausgegeben werden soll? > Verstehe die Frage nicht genau, Ich habe ja einen Grundtakt von meinem > FPGA von 100MHz. Das Datensignal synchronisiere ich damit. Verstehe ich > das gerade falsch? Mir ist nicht klar, was du überhaupt machen willst: welcher Baustein (Name, Typ, Bestellnummer) erzeugt das "Datensignal" und was soll anschließend damit passieren?
Die Beschreibung ist wirklich nicht einfach zu verdauen, einige Begriffe sind wohl "fragwürdig" verwendet. Sawyer M. schrieb: > So entsteht mir > ein kontinuierliches Ausgangssignal Out mit meiner aneinandergereihten > 16Bit Wörtern. Kontinuierlich ist das Gegenstück zu diskret. Du gibst nicht kontinuierlich Werte aus sondern wertediskret und wahrscheinlich auch zeitdiskret (also die Werte ändern sich immer nur zu bestimmten Zeitpunkten, die durch einen Takt gegeben sind (4 MHz). Ich versuche mal zu raten, was du vielleicht meinen könntest: - du betreibst einen externen ADC (irgendwas Delta-Sigma-Mäßiges, das dir im 250kHz-Takt jeweils ein 1-Bit Signal gibt?) - je nach dieser Signalfolge willst du jeweils eines deiner beiden Z auswählen und dieses über ein Schieberegister ausgeben (mit 4MHz-Takt, so dass die vollen 16 Bit mit 250kHz ausgegeben werden). - am Ende einer Ausgabe schaust du dir wieder den aktuellen Eingabewert (ADC-Daten) an und entscheidest, welches Z als nächstes ausgegeben wird. Ist das so ungefähr richtig interpretiert? Was ist dann das Kriterium dafür, ob du Z1 oder Z2 ausgibst? Wenn sich das Eingangssignal seit dem letzten Einlesen geändert hat (Flanke) wählst du Z1, wenn nicht dann Z2? Oder hängt die Auswahl Z1 vs. Z2 von der "Richtugn" der Flanke ab? Oder nur vom aktuellen Pegel des Dateneingangs? Falls letzteres zutrifft: vergiss bitte für den Moment das Sitchwort Flankendetektion. Wenn der Dateneingang schon synchron zum 250kHz Takt vorliegt (d.h. in jeder 16. Periode des 4MHz-Signals ein neuer Dateneingang vorliegt), dann zähle einfach immer 16 Perioden deines 4MHz-Takts ab um das neue Z ins Schieberegister zu schicken. Und zähle die 16*10 Perioden des 4 MHz Takts ab bis du Z3 ausgeben musst. Sawyer M. schrieb: > Spannend wäre auch in den DRAM. Das wäre dann wie eine LUT, oder? Das wäre nicht spannend sondern anstrengend. Und nein, das wäre nicht wie eine LUT. Mit deinen Gedankengängen bist du einfach auf dem Holzweg. Versuch erst mal, die gewünschte Funktion so weit zu durchdringen, dass du sie verständlich darstellen kannst. Danach kannst du dir Gedanken machen, wie die Z am besten gespeichert werden (wahrscheinlich wird sich diese Frage dann gar nicht mehr stellen). Und noch viel später kannst du dich an die spannende Frage machen, wie man ein DRAM mit einem FPGA ansteuert und nutzt. Für diese Aufgabe hier ist das in keiner Weise sinnvoll oder zielführend, es lenkt dich nur von deiner eigentlichen Aufgabenstellung ab und verwirrt die Leser. Für die aktuelle Aufgabe mach es wie von Lothar vorgeschlagen: schreib die drei konstanten Werte einfach in deinen VHDL-Code und überlasse es dem Synthesetool, wie diese genau gespeichert werden.
Achim S. schrieb: > Ich versuche mal zu raten, was du vielleicht meinen könntest: > - du betreibst einen externen ADC (irgendwas Delta-Sigma-Mäßiges, das > dir im 250kHz-Takt jeweils ein 1-Bit Signal gibt?) > - je nach dieser Signalfolge willst du jeweils eines deiner beiden Z > auswählen und dieses über ein Schieberegister ausgeben (mit 4MHz-Takt, > so dass die vollen 16 Bit mit 250kHz ausgegeben werden). > - am Ende einer Ausgabe schaust du dir wieder den aktuellen Eingabewert > (ADC-Daten) an und entscheidest, welches Z als nächstes ausgegeben wird. > > Ist das so ungefähr richtig interpretiert? Ja so kann man es absolut interpretieren. > > Was ist dann das Kriterium dafür, ob du Z1 oder Z2 ausgibst? Wenn sich > das Eingangssignal seit dem letzten Einlesen geändert hat (Flanke) > wählst du Z1, wenn nicht dann Z2? Oder hängt die Auswahl Z1 vs. Z2 von > der "Richtugn" der Flanke ab? Oder nur vom aktuellen Pegel des > Dateneingangs? > Falls letzteres zutrifft: vergiss bitte für den Moment das Sitchwort > Flankendetektion. Wenn der Dateneingang schon synchron zum 250kHz Takt > vorliegt (d.h. in jeder 16. Periode des 4MHz-Signals ein neuer > Dateneingang vorliegt), dann zähle einfach immer 16 Perioden deines > 4MHz-Takts ab um das neue Z ins Schieberegister zu schicken. Und zähle > die 16*10 Perioden des 4 MHz Takts ab bis du Z3 ausgeben musst. Ja hier liegt glaube ich gerade der Hund begraben. Ich glaube ein gravierender Denkfehler hat sich bei mir eingeschlichen. :/ Am Ende meiner ganzen Wortschieberei, will ich ein moduliertes Signal erzeugen auf Basis des Datensignals: Datensignal 250KHz, Das Wort 3 ist ja 1010101010101010. Wenn ich nun nach dem neunten Paket mit 4MHz das Wort ausgebe über ein Schieberegister, dann war das Ziel das ein 8 Bit breites "Taktsignal (ich nenn es nur mal so)" herauskommt. Taktsignal deshalb da ja eine 4MHz Periode, aus einer 10 (high, low) besteht und die Dauer von 250ns hat. Da ja immer nur mit eine fallenden oder steigenden Flanke geschalten wird muss ich deshalb erst das high und low abwarten bis das nächste Bit herausgeschoben wird. Das bedeutet im Umkehrschluss das aus 4MHz, 2MHz werden. Stimmt meine Annahme?? (Bitte nicht erschießen wenn ich falsch liege.) Ziel ist das Wort 3 als 2MHz "Takt" auszugeben. Dafür brauch ich doch 4MHz. Problem, ein 4MHz CLK aus 100MHz CLK benötigt einen Zähler mit 12,5. Somit habe ich nun ein Problem wenn meine Annahme mit den 4MHz richtig ist. Die anderen Wörter sind normalerweise auch 8 Bit breit. Ich habe Sie sozusagen (mit einem Schreibfehler wie mir gerade auffällt sollte Wort 1 (Z1): 1100101011001100) künstlich verbreitert, um am Ende auf ein 8Bit breites Signal zu kommen welches 2MHz wie auch 1MHz Anteile hat. Klar eine 1100 = 1MHz, 1010 = 2MHz.
:
Bearbeitet durch User
Sawyer M. schrieb: > Das bedeutet im Umkehrschluss das aus 4MHz, 2MHz werden. Ja, das ist aber in erster Näherung absolut irrelevant... > Stimmt meine Annahme?? Beantworte doch bitte einfach erst mal meine Fragen. Du nimmst nämlich gerne irgendwas an, das dir irgendwie bekannt vorkommt. Das bringt aber nichts. Du fühst dich selber in die Irre.
:
Bearbeitet durch Moderator
Sawyer M. schrieb: > Stimmt meine Annahme? Ja, dieses Detail deiner Betrachtung stimmt. Aber es ist leider immer noch unklar, nach welchen Kriterien du Z1 oder Z2 auswählst. Sawyer M. schrieb: > Problem, ein 4MHz CLK aus 100MHz CLK benötigt einen Zähler mit > 12,5. Somit habe ich nun ein Problem wenn meine Annahme mit den 4MHz > richtig ist. Das ist überhaupt kein Problem, nur dein Lösungsansatz ist falsch. Das hatten wir doch schon in deinem Parallelthread: Beitrag "VHDL zwei CLK´s mit LFSR und 1:2 Teiler" Wie dort schon erklärt: ein einfacher (und funktionierender) Lösungsansatz wäre, alles mit dem 100MHz-Takt laufen zu lassen. Und das, was du per geteilten Takt erreichen willst, mit dem Einsatz von Clock-Enables zu machen. Es ist überhaupt kein Problem ein CE4MHz Signal zu erzeugen, dass in jeder 25ten Periode des 100MHz Takts für genau einen Taktzyklus auf 1 ist (und die anderen 24 Takte auf 0). Das nutzt du als Clock-Enable Signal für deine FlipFlops und taktest sie weiter mit 100MHz - aber sie werden nur in jedem 25ten Takt wirklich umschalten (so als würden sie mit 4MHz getaktet)
Sodelle ich bin am Projekt dran. Jedoch stolpere ich noch ziemlich oft. Ich habe nun meinen Zähler aufgebaut und bin gerade an der Logik wie ich die drei Zustände schalten kann und könnte. Idee war, die drei Vektoren mit den 16Bits mithilfe von einem MUX in ein Schieberegister zu laden. Zu Testzwecken habe ich deshalb die Variablen F1, F2 und F3 eingeführt. ich wollte bevor ich das Schieberegister aufbaue testen ob alles soweit funktioniert. Fazit: Leider nein. Ich habe eine Taktverzögerung. Man kann es auf dem Bild deutlich sehen. Das Problem ist das ich im Code nicht schreiben kann:
1 | if (rising_edge(data_in) and irq10 = '1') then |
2 | F1 <= '1'; |
3 | elsif (rising_edge(data_in) and irq10 = '0') then |
4 | F2 <= '0'; |
5 | elsif (rising_edge(data_in) and irq10 = '0') then |
6 | F3 <= '1'; |
7 | end if; |
Dann wäre mein Takt synchron aber es wirft Error's. Auch mein Code von dem die Simulation stammt geht nicht.
1 | process(clk) |
2 | begin
|
3 | if rising_edge(clk) then |
4 | if count10 = "1001" then |
5 | count10 <= "0000"; |
6 | clk10 <= not clk10; |
7 | irq10 <= '1'; |
8 | else
|
9 | count10 <= count10 + 1; |
10 | irq10 <= '0'; |
11 | end if; |
12 | end if; |
13 | end process; |
14 | |
15 | |
16 | process(clk, irq10, data_in) |
17 | begin
|
18 | if rising_edge(data_in) then |
19 | |
20 | |
21 | if (data_in = '1' and irq10 = '1') then |
22 | F1 <= '1'; |
23 | elsif (data_in = '1' and irq10 = '0') then |
24 | F2 <= '0'; |
25 | elsif (data_in = '0' and irq10 = '0') then |
26 | F3 <= '1'; |
27 | end if; |
28 | |
29 | end if; |
30 | end process; |
Wie macht man das? Das liegt diesmal ja nicht am Einsynchronisieren, oder? Beste Grüße
:
Bearbeitet durch User
Sawyer M. schrieb: > Das liegt diesmal ja nicht am Einsynchronisieren, > oder? Nein, es liegt daran, dass du ein völlig falsches Konzept verfolgst. Du verwendest datain als Taktsignal. Es ist völlig sinnlos, bei der positiven Taktflanke von datain auch noch den Pegel von datain abzufragen und damit Unterscheidungen treffen zu wollen. Sawyer M. schrieb: > Wie macht man das? Indem man zwischendurch mal Rückfragen beantwortet und versucht, gegebene Ratschläge umzusetzen. Da du offenbar zu beidem keine Lust hast verabschiede ich mich hiermit aus diesem Thema.
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.