Hallo, ich sitze schon seit längerem an einem Schieberegister, welches seriell ankomende Datanpakete zu einem großen zusammenfassen soll. In der Simulation funktioniert dies super geschmeidig. Jedoch funktioniert das Modul nach Synthese nicht mehr. Ich habe mir hierzu den aktuellen Zählindex und den Zustand der FSM ausgeben lassen. Wird beispielsweise ein 18 Bit Vektor verlangt, es kommen aber nur 8 Bit Vektoren an muss dieser 3 Mal in den 18 Bit Vektor geschoben werden, zweimal in voller Länge und einmal nur die ersten 2 Stellen um den vollen 18 Bit Vektor zu erhalten. Hierfür wird ein Counter benutzt, welcher dafür sorgen soll, dass entsprechend ein "Nachschub" signal generiert wird. Wird also der nächste 8 Bit Vektor am eingang benötigt kann dies über da Signal erkannt werden. Nach der Synthese springt der Counter jedoch von 0, nach dem Reset gleich auf 2 und bleibt in diesem Zustand. Ich weiß mittlerweile wirklch nicht mehr wo der Fehler liegen soll. Das Simulationsergebnis, sowie die Testbenche und die Modulbeschreibung hängen an. Ich arbeite für die Synthese mit Quartus prime lite und mit einem DE2-115 Devboard. Ich bin für jeden Hinweis dankbar und für Diskussionen offen. Lieben Gruß, Stephan
Ich hatte zwei verschiedene Quellen für das Freigabesignal der Eingangsdaten ausprobiert. 1. Per Taster (debounced und bei steigender Flanke) - meiner Sicht nach der sicherste Weg 2.Per UART ausgang. Dort habe ich ein Signal für den Zustand des Ausgangs FIFO (o_empty). Das Ausgangs FIFO der UART ist immer leer, sprich o_empty=1, solange keine Date anliegt. So habe ich auch mal das invertierte (o_empty_n) als Freigabesignal für das Besagte Modul genutzt. Selbstverständlich habe ich darauf geachtet, dass mit dem Lesen des UART FIFOs dieses wieder geleert wird, sprich eine Valide Date und somit auch das Freigabe Signal nur für einen Takt anliegt.
Stephan K. schrieb: > Nach der Synthese springt der Counter jedoch von 0, nach dem Reset > gleich auf 2 und bleibt in diesem Zustand. Ich würde das Reset-Signal (und alle anderen asynchronen Signale) vor der internen Verwendung einsynchronisiseren. Sonst kann es Dir passieren, das beim Verlassen des Reset-Zustandes Teile des Designs schon losrennen, während andere Teile noch den Reset sehen. Die Effekte sehen dann so aus, wie von Dir beschrieben. Ich hatte mal Spaß mit einer UART-Implementierung, bei der das RX-Signal an zwei Stellen in einer Statemachine abgefragt wurde. Per LED-Debugging stellte ich fest, das immer wenn die Übertragung festging, zwei States auf einmal aktiv waren (von wegen one-hot...). Nach Einsynchronisierung von RX lief es plötzlich fehlerfrei. Duke
Sonst vielleicht mal irgendwie dieses data_valid verifizieren. Die generics für c_cnt_max sind richtig gesetzt? Ich würde jetzt in der Entity eher den Generics default Werte zuweisen anstatt den Ports.
Einsynchronisiert sollten die Signale eigentlich alle sein, in dem Modul ist extra ein Prozess zur Synchronisierung der Ein- und Ausgangssignale vorgesehen. Unabhängig davon, ob diese svhon synchron eingehen. Aber guter Tip, durchs LED debuging bin ich selbst auch erst auf die Idee gekommen, dass es am Counter liegen könnte. Die defaultzuweisung der generic ports fehlt, das stimmt. Werde ich mal ändern. In der Komponentenzuweisung in der Top-Entity sind diese aber gemappt. Passend zum genannten Brispiel, sowie der Testbench g_wordwidth_in => 8, g_wordwidth_long => 18, g_type => "long"
Das enable in den FF für den Zustandsvektor ist designtechnisch fragwürdig:
1 | state_register : process(i_clk,i_reset) |
2 | begin
|
3 | if (i_reset = '1') then |
4 | -- stateregister
|
5 | w_state_reg <= idle; |
6 | |
7 | elsif (rising_edge(i_clk)) then |
8 | if (i_enable = '1') then --für w_state_reg keine gute Idee, hier sollte ein D-FF benutzt werden |
9 | w_state_reg <= w_state_next; |
10 | |
11 | end if; |
12 | end process state_register; |
Also ich habe grade nur die Xilinx ISE 17 da, wenn ich dein "mini_merge_data.vhd" da einfach mal rein kippe, kommen solche Warnungen bei der Synthese: --- WARNING:Xst:737 - Found 1-bit latch for signal <o_busy>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems. WARNING:Xst:737 - Found 1-bit latch for signal <w_index_next<1>>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems. WARNING:Xst:737 - Found 1-bit latch for signal <w_index_next<0>>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems. usw usw... --- Was sagt deine Quartus Synthese zu den Latches, geht das bei Altera? Beim Xilinx würde ich da im FPGA mit Latches Schwierigkeiten erwarten!
Code - Polier schrieb: > if (i_enable = '1') then --für w_state_reg keine gute Idee, hier > sollte ein D-FF benutzt werden Das wird sowieso ein D-Flipflop. Innerhalb eines FPGA gibt es gar nichts anderes... Stephan K. schrieb: > In der Simulation funktioniert dies super geschmeidig. > Jedoch funktioniert das Modul nach Synthese nicht mehr. In der Praxis kommt das zu 99% von nicht synchronisierten Eingängen. Zuvor jedoch sollte drauf geachtet werden, dass in den Timing Constraints wenigstens der Takt angegeben ist. > Einsynchronisiert sollten die Signale eigentlich alle sein... > if (i_reset = '1') then Geht der asynchrone Reset auch synchron weg? > Nach der Synthese springt der Counter jedoch Ich finde das Wort "Counter" nur in Kommentaren. Welcher "Counter" ist denn gemeint? > von 0, nach dem Reset gleich auf 2 "Gleich" fürs Auge, oder "gleich" für den Logikanalyzer? Er springt von 0 nach 2 ohne einen einzigen Takt lang 1 zu sein? > in dem Modul ist extra ein Prozess zur Synchronisierung Man braucht zum Eintakten keinen "Prozess", sondern man braucht zwei "Flipflops" hintereinander. Das geht problemlos auch ohne Prozess. > -- shift residual data length Du hast dort keinerlei Schieberegister, sondern du arbeitest mit recht großen Multiplexern. Das macht das Design tendenziell langsam. Das hier geht übrigens nicht:
1 | i_data : in std_logic_vector(g_i_wordwith-1 downto 0) := (others => '0'); |
Du kannst Eingänge nicht initialisieren, weil sie nicht speichern können. Du kannst nur Ausgänge initialisieren, die an Flipflops angeschlossen sind. Dann wird diesen FLipflops beim Laden des FPGAs der Initwert gegeben. > Wird beispielsweise ein 18 Bit Vektor verlangt, es kommen aber nur 8 Bit > Vektoren an muss dieser 3 Mal in den 18 Bit Vektor geschoben werden, > zweimal in voller Länge und einmal nur die ersten 2 Stellen um den > vollen 18 Bit Vektor zu erhalten. Und wie geht es danach weiter? Werden die verbleibenden 6 Bit für die nächsten 18 Bit verwendet, oder werden diese 6 Bit "weggeworfen"? BTW: wenn schon unbedingt englische Kommentare und Datumsangaben, dann auch richtige englische Kommentare und Datumsangaben. Über sowas lacht der Anglikaner: ... FSM defination ... 23/06/17 ... Oder eben einfach in deutsch, wenn sowieso keine Gefahr besteht, dass BTW2: ich bekomme irgendwie Krätze ans Auge, wenn ich solchen durch Unterstriche "gestretchen" Code lesen muss. EDIT: Bernhard K. schrieb: > WARNING:Xst:737 - Found 1-bit latch for signal <w_index_next<0> Autsch. Ein Latch in einem Zähler. Das geht garantiert ins Auge, weil Latches auch durch kurze Glitches andere Werte annehmen können (und werden).
:
Bearbeitet durch Moderator
Stephan K. schrieb: > Einsynchronisiert sollten die Signale eigentlich alle sein, in dem Modul > ist extra ein Prozess zur Synchronisierung der Ein- und Ausgangssignale > vorgesehen. Fast alle. i_enable wird z.B. nicht einsynchronisiert, geht aber direkt in die State-Übergänge ein. Wenn i_enable im falschen Moment umschaltet sind unvorhergesehene State-Übergänge vorprogrammiert. Das hatte wohl auch Code-Polier in seinem Beitrag weiter oben gemeint. Zu den Latches: Bernhard K. schrieb: > WARNING:Xst:737 - Found 1-bit latch for signal <o_busy>. Das passiert bei der Zwei-Prozess-Schreibweise gerne mal. Du musst den Signalen, denen du in state_output_logic etwas zuweist, immer etwas zuweisen - nicht nur, wenn die if - then - elsif - Kette das zufällig ergibt. Ein Konstrukt wie else w_state_next <= idle; end if; bedeutet: alle anderen Signale außer w_state_next, denen in diesem Prozess ein Wert zugewiesen werden könnte, müssen für diese Konstellation der Steuersignale ihren alten Inhalt per Latch speichern ( z.B. w_index_next). Eine Möglichkeit wäre eine "Default-Zuweisung" für "alle" Signale zu Beginn des Prozesses, in dem allen Signalen ihr (im FF gespeicherter) Wert wieder zugewiesen wird. Also z.B.: w_index_next <= w_index_reg; "Weiter unten im Prozess" kannst du w_index_next ja immer noch mit neuen Werten überschreiben. Weniger Schreibarbeit hast du, wenn du auf die Ein-Prozess-Schreibweise umsteigst.
Bernhard K. schrieb: > Warnungen bei der Synthese: > --- > WARNING:Xst:737 - Found 1-bit latch for signal <o_busy>. Latches may be > generated from incomplete case or if statements. We do not recommend the > use of latches in FPGA/CPLD designs, as they may lead to timing > problems. > usw usw... > --- > Was sagt deine Quartus Synthese zu den Latches, geht das bei Altera? > Beim Xilinx würde ich da im FPGA mit Latches Schwierigkeiten erwarten! Quartus meldet: Warning (10631): VHDL Process Statement warning at merge_data.vhd(175): inferring latch(es) for signal or variable "o_busy", which holds its previous value in one or more paths through the process Um ehrlich zu sein war mir bisher der genaue Unterschied zwischen einem Latch und einem FF jedoch nicht nicht ganz klar weshalb ich diese Meldunge mehr oder minder ignoriert habe. Lothar Miller schrieb: > In der Praxis kommt das zu 99% von nicht synchronisierten Eingängen. > Zuvor jedoch sollte drauf geachtet werden, dass in den Timing > Constraints wenigstens der Takt angegeben ist. Liegt ganz bestimmt am timing, jedenfalls ergibt sich für Timing Analyse mit Quartus' TimeQuest an einigen Stellen ein neativer Slack. Ich weiß nur nicht, wie ich damit umgehen soll, hierzu fehlt mir noch das Wissen und die Erfahrung, beschäftige mich erst seit 5 Monaten mit dem Thema VHDL und FPGA, generell der ganzen Digitaltechnik. Lothar Miller schrieb: > Geht der asynchrone Reset auch synchron weg? Die Clock, der Reset und das Enable-Signal werden nicht synchronisiert. Aber der Rest dachte ich?! Lothar Miller schrieb: > Welcher "Counter" ist denn gemeint? Der Counter, der den Index für die eingehenden Datenpakete zählt. w_index_reg / w_index_next. Lothar Miller schrieb: > Er springt von 0 nach 2 ohne einen einzigen Takt lang 1 zu sein? Rein optisch tut er das, ich weiß leider grad nicht, wie ich feststellen könnte, ob zumindest einen Takt lang eine 1 erscheint. Lothar Miller schrieb: > Synchronisierung problemlos auch ohne Prozess. Schon, aber ist die Gestaltung mittels Prozess nicht bei vielen Signalen sinvoll? Ähnlich passiert es dann ja auch bei der Ein-Prozess-Schreibweise. Lothar Miller schrieb: > Du hast dort keinerlei Schieberegister :/ Ich dachte es sei eins.. Oh man, gibt ja noch einiges zu lernen. Danke auch an dieser Stelle für den Hinweis, dass Eingänge nicht mit einem Initialwert versehen werden können. Lothar Miller schrieb: > werden diese 6 Bit "weggeworfen"? Die übriggebliebenen Bits werden "weggeworfen". Lothar Miller schrieb: > BTW1&2: Das mit der Rechtschreibung lässt sich verbessern. Wie soll ich denn aber mit der Kommentierung umgehen? Den Code leserlicher gestalten? Habe bisher noch keine Styling-Richtlinien zu VHDl gesehen, bzw. ist man sich - so scheint es mir - da draußen in der großen Welt nicht ganz einig, was das betrifft. > Achim S. schrieb: > i_enable wird z.B. nicht einsynchronisiert Stimmt, wird aber ja doch nur mit der steigenden Flanke der Clock berücksichtigt. > Achim S. schrieb: > Eine Möglichkeit wäre eine "Default-Zuweisung" für "alle" Signale zu > Beginn des Prozesses, in dem allen Signalen ihr (im FF gespeicherter) > Wert wieder zugewiesen wird. Das ist ein wirklich guter Tip, ich war mir bisher über die Dafault-Zuweisung nicht ganz bewusst. Danke! Auch der Vorschlag mit der Ein-Prozess-Schreibweise werde ich, denke ich, in Zukunft berücksichtigen.
Stephan K. schrieb: > Stimmt, wird aber ja doch nur mit der steigenden Flanke der Clock > berücksichtigt und wenn sich der Pegel von i_enable genau bei der steigenden Flanke der Clock ändert, kommt Murx raus - weil ein teil der Statemachine noch "den alten Wert sieht", ein anderer Teil aber schon den neuen. Damit kannst du in States landen, die es nach deiner VHDL-Beschreibung "eigentlich" gar nicht geben sollte. Genau deshalb ist das Einsynchronisieren nötig - fehlt aber bei dir bei einem Teil der Signale.
Stephan K. schrieb: > Lothar Miller schrieb: >> werden diese 6 Bit "weggeworfen"? > Die übriggebliebenen Bits werden "weggeworfen". Dann ist es ehrlich gesagt unheimlich einfach: du bauchst nur ein ausreichend breites "Pufferregister", in das die Bytes nacheinander hineingeschrieben werden. Und zum Schluss werden nur die benötigten Bits ausgegeben. Das ist in Hardware einfach zu realisieren und deshalb nur ein besserer Dreizeiler in VHDL: ein Zähler und die nötigen Multiplexer für die Eingangsdaten. Das wars... > Lothar Miller schrieb: >> Er springt von 0 nach 2 ohne einen einzigen Takt lang 1 zu sein? > Rein optisch tut er das, ich weiß leider grad nicht, wie ich feststellen > könnte, ob zumindest einen Takt lang eine 1 erscheint. Oszilloskop oder Logikanalyzer. > Stimmt, wird aber ja doch nur mit der steigenden Flanke der Clock > berücksichtigt. Siehe das da: http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren Dein asynchrones i_enable geht auf viele Flipflops. Und wenn dieser i_enable-Impuls zur unpassenden Zeit kommt, dann "sehen" den nur die Hälfte der Flipflops. Ergebnis: ein paar Flipflops werden auf den neuen Zustand gesetzt, die anderen bleiben noch im alten Zustand --> Chaos --> amoklaufende FSM (und jeder Zähler ist eine FSM!). Aber asynchrone Eingänge sorgen eher dafür, dass so ein Fehler sporadisch und variabel auftritt. Das ist hier ja offenbar nicht der Fall... > Lothar Miller schrieb: >> BTW1&2: > Wie soll ich denn aber mit der Kommentierung umgehen? Kommentiere doch einfach Deutsch. > Den Code leserlicher gestalten? > Habe bisher noch keine Styling-Richtlinien zu VHDl gesehen, bzw. ist man > sich - so scheint es mir - da draußen in der großen Welt nicht ganz > einig, was das betrifft. Sicher, aber sieh dir einfach mal ein paar VHDL-Texte an und überleg dir selber, welchen davon du flüssig "lesen" und verstehen kannst. Das ist dann ein brauchbarer Stil, solange keine weiteren Vorgaben da sind. Aber das führende o_ hier verwirrt mehr als es hilft: o_data_long_s <= o_data_long; Denn in VHDL kann ich keinen Ausgang lesen. Wie soll das also gehen? Da muss man schon gleich wieder nachschauen, um zu sehen, dass o_data_long trotz des wohlklingenden Namens kein Ausgang sondern ein Signal ist.
:
Bearbeitet durch Moderator
Achim S. schrieb: > und wenn sich der Pegel von i_enable genau bei der steigenden Flanke der > Clock ändert, kommt Murx raus - weil ein teil der Statemachine noch "den > alten Wert sieht", ein anderer Teil aber schon den neuen. > > Damit kannst du in States landen, die es nach deiner VHDL-Beschreibung > "eigentlich" gar nicht geben sollte. Genau deshalb ist das > Einsynchronisieren nötig - fehlt aber bei dir bei einem Teil der > Signale. Verstehe. An diesen Fall hatte ich offensichtlich noch nicht gedacht.
Lothar M. schrieb: > Code - Polier schrieb: >> if (i_enable = '1') then --für w_state_reg keine gute Idee, hier >> sollte ein D-FF benutzt werden > Das wird sowieso ein D-Flipflop. Innerhalb eines FPGA gibt es gar nichts > anderes... Nö, das wird kein D-FF sondern ein DEN-FF -> Delay-Flipflop mit Enable. Der Unterschied mag klein klingen führt aber hier zu einer "eigenartigen" FSM. Für eine FSM wird der nächste Zustandsvektor kombinatorisch ermittelt. Und dieser Zustandsvektor wird immer (also ohne enable) in FF abgespeichert. Wenn ein enable dann ist das kombinatorisch zu behandeln. Anders sind die FSM Zustandgleichungen nicht sauber implementierbar. http://wwwlehre.dhbw-stuttgart.de/~srupp/EDS/Entwurf_digitaler_Systeme_T2ELN3602_1_SR.pdf S. 45 ff. BTW: wie sieht überhaupt das Timing aus, sind da constraints gesetzt und werden die erfüllt?
Achim S. schrieb: > Stephan K. schrieb: >> Einsynchronisiert sollten die Signale eigentlich alle sein, in dem Modul >> ist extra ein Prozess zur Synchronisierung der Ein- und Ausgangssignale >> vorgesehen. > > Fast alle. i_enable wird z.B. nicht einsynchronisiert, geht aber direkt > in die State-Übergänge ein. Wenn i_enable im falschen Moment umschaltet > sind unvorhergesehene State-Übergänge vorprogrammiert. Das hatte wohl > auch Code-Polier in seinem Beitrag weiter oben gemeint. Nicht ganz, aber doch. Das Enable ist da IMHO unpassend, das gehört in die Übergangslogik. Und wenn es in Übergangslogik ist (wenn man wirklich eine FSM mit enable für jeden State will) dann schaut ob jedes einzelne Signal Eingangssignal ob es einsynchronisiert resp von FF in der richtigen Taktdomain getrieben ist. Ist es nicht einsynchronisiert, kann die FSM quer durch den Zustandsraum hoppeln und sogar undefinierte Zustände annehmen aus denen man ohne reset nie mehr rauskommt. Und enable für jeden FSM-Transition ist eigentlich "ungewöhnlich" normalerweise hat man einen IDLE state dessen verlassen vom Statmchine enable bestimmt wird, die abgehenden Zweige werden dann unabhängig vom enable durchgetackert, so das die FSM wieder zugig den Hauptzustand (IDLE) erreicht.
Code - Polier schrieb: > Nicht ganz, aber doch. Das Enable ist da IMHO unpassend, das gehört in > die Übergangslogik. Und wenn es in Übergangslogik ist (wenn man wirklich > eine FSM mit enable für jeden State will) dann schaut ob jedes einzelne > Signal Eingangssignal ob es einsynchronisiert resp von FF in der > richtigen Taktdomain getrieben ist Das ist doch nur Schreibstil. Was die Toolchain draus macht, steht auf einem anderen Blatt. Nach meiner Erfahrung verwendet der Synthesizer das Enable so, wie es für ihn optimal ist. Er kann das Enable genausogut in die LUT packen und dadurch das Weiterschalten der FSM verhindern. Code - Polier schrieb: > Wenn ein enable dann ist das kombinatorisch zu behandeln. Anders sind > die FSM Zustandgleichungen nicht sauber implementierbar. Das verstehe ich nicht. Und finde auch im verlinkten PDF irgendwie keinen Zusammenhang.
Lothar M. schrieb: > Code - Polier schrieb: >> Nicht ganz, aber doch. Das Enable ist da IMHO unpassend, das gehört in >> die Übergangslogik. Und wenn es in Übergangslogik ist (wenn man wirklich >> eine FSM mit enable für jeden State will) dann schaut ob jedes einzelne >> Signal Eingangssignal ob es einsynchronisiert resp von FF in der >> richtigen Taktdomain getrieben ist > Das ist doch nur Schreibstil. Was die Toolchain draus macht, steht auf > einem anderen Blatt. Nach meiner Erfahrung verwendet der Synthesizer das > Enable so, wie es für ihn optimal ist. Er kann das Enable genausogut in > die LUT packen und dadurch das Weiterschalten der FSM verhindern. Nach meiner Erfahrung nicht. Wenn es als enable beschrieben ist (if ena = '1' then state_q <= state_q dann nimmt er das in den enablezweig und bastelt es nicht in den D-Zweig. Aber du hast sicher recht, pauschal kann man das nicht beantworten, mglw nimmt das Synthese-tool da noch ((Schein)-Optimale) Umwandlungen vor. > Code - Polier schrieb: >> Wenn ein enable dann ist das kombinatorisch zu behandeln. Anders sind >> die FSM Zustandgleichungen nicht sauber implementierbar. > Das verstehe ich nicht. Und finde auch im verlinkten PDF irgendwie > keinen Zusammenhang. Der Zusammenhang zeigt sich auf Seite 55 im Beispielcode. Ich verstehe die Zustandgleichung: Z(t+1) = f(Z(t),x(t)) so das, es kein enable geben darf, sonst hieße die grundlegende Zusstandgleichung der FSM: Z(t+1) = f(Z(t),x(t)) falls ena = '1'; sonst = Z(t) Aber das ist womöglich zu "akademisch" gedacht.
Code - Polier schrieb: > Ich verstehe die Zustandgleichung: > Z(t+1) = f(Z(t),x(t)) so das, es kein enable geben darf Ach, ok, in der Systemtheorie stimmt das. Ich bin da mit meiner Denkweise gern ein, zwei Ebenen weiter unten in der Hardware... ;-)
Code - Polier schrieb: > BTW: wie sieht überhaupt das Timing aus, sind da constraints gesetzt und > werden die erfüllt? Es sind noch keine Constrains gesetzt worden, ich wüsste zumindest noch nicht, wie ich das in Quartus bewerkstellige. Mit dem Timing hatte ich mich eben noch nicht intensiv auseinander gesetzt. Code - Polier schrieb: >Und enable für jeden FSM-Transition ist eigentlich "ungewöhnlich" Ich denke das i_enable lasse ich im nächsten FSM-Design auch weg, wie schon angesprochen, sorgt der Zustand "Idle" schon für eine entsprechende Wirkung..
Stephan K. schrieb: > Es sind noch keine Constrains gesetzt worden Du musst mindestens den Takt angeben. Denn sonst ist die Toolchain auch zufrieden, wenn das Design mit 10Hz läuft. Und das darf sie auch, denn du hattest da ja keine näheren Wünsche...
:
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.