Hallo Ich bin gerade etwas am verzweifeln: Bei einem kleinen Schulprojekt soll ein RFID Empfänger über VHDL beschrieben werden. Sollte kein Problem sein. Nur kommen jetzt die Tücken von VHDL hinzu? Als Eingang ist ein Manchester-Codiertes Datensignal, welches leider nicht synchron auf die Referenz ändert (immer etwas verschoben und nicht konstant zu RDY_CLK). Jetzt kommt das interessante: Die Simulation klappt ohne Fehler (alles), dann wird alles richtig synthetisiert und am Schluss läuft alles anders auf der Hardware, als vorhin die Simulation, die Gedanken und dann die "Analyse" des Codes. Z.B. Wird ein Paket richtig empfangen (also die 9 '1' des Headers werden gelesen) doch dann springt er mir irgendwie in das Fehlerhandlich, indem ich die Abtastzeit um eine halbe Periode verschiebe. Und dies macht es schön regelmässig. Eigentlich sollte maximal nach einem Wechsel der Header korrekt gelesen werden können. Man ich kann echt kein VHDL. In C hätte ich das in etwa 4h ohne Probleme hingekriegt, aber hier bin ich nun schon eine Woche dran, und es läuft immer noch nicht. Ausserdem kann man das zeugs ja nichtmal richtig debugen (irgendwie eine Art Breakpoint setzen). Könnte mir vieleicht jemand mal etwas helfen (und auch Verbesserungen anbringen)? Wie gesagt, Programmieren ist kein Problem aber VHDL?! Eine Welt für sich. Gruss Patrick
:
Bearbeitet durch User
Patrick B. schrieb: > Man ich kann echt kein VHDL. In C hätte ich das in etwa 4h ohne Probleme > hingekriegt, Das sieht man klar&deutlich: ein Softie, der Hardware machen muss. Schon die überaus exzessive Verwendung bon Variablen... Wenn ich mir die daraus entstehende Monsterlogik so überlege, dann frage ich dich: welche Taktfrequenz hast du? Und: hast du das der Toolchain auch gesagt?
:
Bearbeitet durch Moderator
Mhm, also laufen soll das ganze auf einem Spartan 3e mit 50MHz Takt, der aber ev noch auf 1MHz heruntergeteilt wird. Das RDY_CLK Signal hat 125kHz wobei das Datensignal 64 Clockzyklen braucht (also noch langsamer). Verbesserungsvorschlag? Wie soll ich das den sonst aufbauen/struckturieren?
Patrick B. schrieb: > laufen soll das ganze auf einem Spartan 3e mit 50MHz Takt Weiß die Toolchain das? Welche Taktfrequenz gibt der Report aus? Hast du entsprechende Constraints angegeben? Dir muss klar werden, dass die Parity-Berechnung in der Hardware immer da ist und immer gemacht wird. Aber nur im Zustand parity_check wird das Ergebnis der Berechnung weiterverwendet. > Verbesserungsvorschlag? Einen Teil der Parity-Berechnung kannst du sicher schon bei der Übertragung jedes einzelnen Bits berechnen:
1 | when save => |
2 | bit_cnt <= bit_cnt + 1; -- Gesampelte Bits |
3 | data_shift_reg <= data_shift_reg(62 downto 0) & demod_sync(0); |
Denn dort sind die Bits ja noch alle hübsch seriell. Später musst du sie erst wieder über viel Logik (das wird aus deinen for-Schleifen gemacht!!) miteinander ver-xor-en... Muss der komplette Check unbedingt in 1 Takt ablaufen? Wenn nicht, dann könntest du den Check auch über einen Automaten Schritt für Schritt ablaufen lassen. > Debug-Signal Dein Debug-Signal hat übrigens einen Takt Latency, weil du es im getakteten Prozess zuweist. Die Debugausgabe könntest du auch so machen, das spart ein paar Zeilen: http://www.lothar-miller.de/s9y/archives/49-FSM-debuggen.html > delay_cnt_max, edge_cnt, bit_cnt Hier ist die Zählrichtung ungünstig: besser du lädst die Zähler mit 0 und zählst hoch. Denn dann kann zum "Laden" (=Rücksetzen) der Reset-Eingang der Flipflops genommen werden. Zum Auswerten des Zählerendes braucht man sowieso Logik. > Nibbel Sagen wir mal lieber Nibble, das ist weniger verfänglich... > process(clk2, reset, state, rdy_clk_sync, demod_sync, ..... Dieser Prozess ist lediglich auf den clk2 sensitiv. > data_shift_reg(63 downto 0) <= (others => '0'); Das ginge kürzer so: data_shift_reg <= (others => '0');
Lothar Miller schrieb: > Patrick B. schrieb: >> laufen soll das ganze auf einem Spartan 3e mit 50MHz Takt > Weiß die Toolchain das? Welche Taktfrequenz gibt der Report aus? Hast du > entsprechende Constraints angegeben? Ich benutze die Xilinx ISE und habe beim Projekt schon das Spartan 3e Starterkit angegeben. Eine Taktfrequenz wäre mir bis jetzt noch nicht begegnet. >> Verbesserungsvorschlag? > Einen Teil der Parity-Berechnung kannst du sicher schon bei der > Übertragung jedes einzelnen Bits berechnen: >
1 | > when save => |
2 | > bit_cnt <= bit_cnt + 1; -- |
3 | > Gesampelte Bits |
4 | > data_shift_reg <= data_shift_reg(62 downto 0) & |
5 | > demod_sync(0); |
6 | >
|
> Denn dort sind die Bits ja noch alle hübsch seriell. Später musst du sie > erst wieder über viel Logik (das wird aus deinen for-Schleifen > gemacht!!) miteinander ver-xor-en... Das Problem ist hier, dass es eine Kreuzparität ist: 9-Bit Header (alle 1), 4-Bit Daten + 1 Parität, 4-Bit Daten + 1 Parität .... und am Schluss 4 Bit Parität und 1 Stopbit. Also müsste ich sowieso irgendwas wie ein Zähler haben, der mir die Bits zählt und dann die Pakete mit der Parität verlgeicht. > Muss der komplette Check unbedingt in 1 Takt ablaufen? Wenn nicht, dann > könntest du den Check auch über einen Automaten Schritt für Schritt > ablaufen lassen. Nein, überhaupt nicht. Mir ist nur gerade kein anderer Lösungsansatz in den Sinn gekommen. Werde dann das Ganze mal etwas umbauen.
Patrick B. schrieb: > Werde dann das Ganze mal etwas umbauen. Gib der Toolchain zuerst mal ein Clock-Constraint vor. Vielleicht hilft das schon. Aber auf jeden Fall bekommst du einen Fehler, wenn sie die 50MHz nicht schafft.
Nur mal so nebenbei - aber keineswegs OT - wann immer bei mir die Simulation sich korrekt verhielt, die Implementation aber nicht wie erwartet, hat sich der streng prüfende Blick in das Constraint-File gelohnt. Nicht zugewiesene Signale (das kann bei per C&P erstellten Dateien schnell mal passieren) führen in der ISE Toolchain dazu, das der PAR Prozess sie auf irgendein freies IOB legt, was erst der Blick in den FPGA Editor enthüllt - sofern man ihn denn öffnet. Damit lässt sich viel Spaß haben - mein Klassiker war ein vergessenes Reset Signal. Gruß, Burkhard
Burkhard K. schrieb: > das der PAR > Prozess sie auf irgendein freies IOB legt, was erst der Blick in den > FPGA Editor enthüllt Wahlweise gibt es einen .pad-Report. Der dürfte in diesem Fall übersichtlicher sein, als der FPGA-Editor. Duke
Lothar Miller schrieb: > Gib der Toolchain zuerst mal ein Clock-Constraint vor. Vielleicht hilft > das schon. Aber auf jeden Fall bekommst du einen Fehler, wenn sie die > 50MHz nicht schafft. Habs mal etwas umgebaut: den ganzen Teil mit der Kreuzparität auskommentiert und die erwähnten Vorschläge umgesetzt. Ebenso im ucf-File das Clockconstraint definiert (gemäss IG230)
1 | NET "CLK" LOC = "C9" | IOSTANDARD = LVCMOS33; |
2 | NET "CLK" PERIOD = 20.0ns HIGH 40%; |
Ebenso der bit_cnt auskommentiert. Dort sollte nur der Sampelzeitpunkt nach 2 Misserfolgen geändert. Hat zwar zusätzliches Fehlverhalten generiert (da keine Prüfung mehr), aber die Synthese läuft immer noch ohne Wahrnung durch. Werde morgen mal mit dem LA weitersuchen.
Patrick B. schrieb: > NET "CLK" LOC = "C9" | IOSTANDARD = LVCMOS33; > NET "CLK" PERIOD = 20.0ns HIGH 40%; In deinem Beispielcode hiess dein Taktnetz aber "clk2" und nicht "clk" Also:
1 | NET "CLK2" PERIOD = 20.0ns HIGH 40% |
Wie viele Takte hat dein Design und wie sehen die Taktdomänenübergänge aus?
Habe jetzt das ganze etwas umgebaut und noch "verschönert". Das Fehlverhalten konnte ich auf den letzten State eingenzen: Wenn ich im update_output in wait_rdy_clk_edges mit 64 Takten wechsle gehts. Wieso auch immer, denn ich verarbeite alles vor der neuen Flanke, die ich im idle auswerte. Dann wieder mit 16 Takten Wartezeit neu synchronisiere, und beim Wechsel zu save sind identische Taktzyklen von rdy_clk vergangen. Mhm, muss da wohl noch etwas genauer dahinter. alex schrieb: > Wie viele Takte hat dein Design und wie sehen die Taktdomänenübergänge > aus? Öhm, ich habe vieleich erst 40h VHDL "Erfahrungen". Was genau meinst du damit und wie kann man das anschauen/herausfindig machen? Noch eine generelle Frage (oder 2): Ich habe öfters gesehen, dass es 1 oder 2-Prozessschreibweisen für eine Statemachine gibt. Was ist der Vorteil von 2? Ich konnte so überhaupt nicht arbeiten, da es unüberischtlich ist und man nur aus einem Prozess in die Signale schreiben kann. Ist es sinnfoll, Prozesse zu machen, die nur die Flanke eines Signals auswerten, oder ähnliches? Eine grobe Segmentierung sozusagen. Danke für eure Geduld. Gruss
Patrick B. schrieb: > Ich habe öfters gesehen, dass es 1 oder 2-Prozessschreibweisen für eine > Statemachine gibt. Was ist der Vorteil von 2? Du hast die Kombinatorik und die Speicherelemente getrennt. Du berechnest explizit im kombinatorischen Prozess den Zustand, der mit der nächsten Taktflanke übernommen wird. Ich nehme auch die Ein-Prozess-Schreibweise, weil dort einige Fehler gar nicht möglich sind: http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html > Ist es sinnfoll, Prozesse zu machen, die nur die Flanke eines Signals > auswerten, oder ähnliches? Eine grobe Segmentierung sozusagen. Wenn man diese Flanke an vielen Stellen der restlichen Beschreibung braucht, dann schon. Sonst schreibe gern alles im selben Prozess.
:
Bearbeitet durch Moderator
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.