Hallo, ich habe eine (relativ) große FSM, wobei ein paar Zustände nochmal unterzustände haben. Jetzt habe ich den Zustand, das jeder Zustand genau 2 mal getriggert wird(wenn ich durchdebugge). Grund dafür sind Flankenübergänge zu den entsprechenden Zeitpunkten. Ich habe einen Counter, der in der Empfindlichkeitsliste steht(aber nicht müsste, das würde mein Ergebniss nicht verfälschen!), der diese "doppelten" Triggerungen auslöst. Ist es eine akzeptable Lösung den Counter einfach aus der Empfindlichkeitsliste zu werfen? Ist das dann auch, im Verhalten, so synthetisierbar?
vhdl-anfänger schrieb: > Ist es eine akzeptable Lösung den Counter einfach aus der > Empfindlichkeitsliste zu werfen? Den Rest habe ich nicht nachvollzogen, aber das ist keine Lösung. Die Empfindlichkeitsliste hat nur für die Simulation Relevanz. Wenn die falsch ist, stimmt die Simulation nicht mehr mit dem realen Verhalten überein.
Im Normalfall sollte überhaupt nur der Takt in der Sensitivity-List stehen, weil alle Zustandsübergänge nur mit einer Taktflanke passieren- Reset ist noch erlaubt, aber sonst nix. Deine Beschreibung klingt aber insgesamt etwas komisch, gibts Codebeispiele?
:
Bearbeitet durch User
Georg A. schrieb: > Im Normalfall sollte überhaupt nur der Takt in der > Sensitivity-List > stehen, weil alle Zustandsübergänge nur mit einer Taktflanke passieren- > Reset ist noch erlaubt, aber sonst nix. Deine Beschreibung klingt aber > insgesamt etwas komisch, gibts Codebeispiele? aber doch nicht für einen kombinatorischen Prozess!?!
vhdl-anfänger schrieb: > aber doch nicht für einen kombinatorischen Prozess!?! Das stimmt. Es sollten alle Signale in der Liste stehen, die eine Neuberechnung nötig machen. Zu wenige Signale kann die Simulation falsch machen, zu viele stört meines Wissens nicht, außer dass die Simulation eventuell langsamer wird.
Dussel schrieb: > Es sollten alle Signale in der Liste stehen, die eine > Neuberechnung nötig machen. Zu wenige Signale kann die Simulation falsch > machen, zu viele stört meines Wissens nicht, außer dass die Simulation > eventuell langsamer wird. Aber weglassen von Signalen führt zu einer HW, die nicht das macht was ich in der Simulation erwarte...?!?
vhdl-anfänger schrieb: > Aber weglassen von Signalen führt zu einer HW, die nicht das macht was > ich in der Simulation erwarte...?!? Das habe ich doch geschrieben. Zu wenige Signale in der Liste: Simulation falsch Zu viele Signale in der Liste: Simulation langsamer
> aber doch nicht für einen kombinatorischen Prozess!?!
Davon hast du nichts geschrieben ;) Du machst also die 2 bzw.
3-Prozess-Variante einer FSM? Hast du überhaupt einen Takt? Deine
doppelten Triggerungen dürften mit Takt nämlich auch nicht auftreten...
BTW: Man kann schon in seltenen Notfällen ohne Takt arbeiten, aber
Anfänger sollten davon die Finger lassen.
vhdl-anfänger schrieb: > ich habe eine (relativ) große FSM Lass doch mal sehen. Einfach die *.vhd oder *.vhdl Datei hier anhängen... Zum Thema Ein- und Zwei-Porzess-Schreibweise den da: http://www.lothar-miller.de/s9y/archives/43-Ein-oder-Zwei-Prozess-Schreibweise-fuer-FSM.html
Ein kleiner Exkurs zum Thema Prozesse. Eigentlich hat kombinatorische Logik in einem Prozess überhaupt nichts zu suchen, da ein VHDL-Prozess ein synchrones Sprachelement ist. Der Zweck eines Prozesses ist es, eine logische Funktion zu beschreiben, die nur zu bestimmten Zeitpunkten, also nur bei der Änderung eines bestimmten Signalzustandes, ausgewertet wird. Genau das ist bei kombinatrischer Logik nicht erwünscht, die soll ihren Zustand sofort ändern, wenn irgendeines der Eingangssignale wechselt. Daher ist es streng genommen Unsinn, Kombinatorik in Prozesse zu kapseln. Wie auch immer, verboten ist es nicht, und man erhält mitunter übersichtlicheren Code, wenn man komplexe Logik in einen Prozess packt. Das liegt daran, dass man in einem Prozess Sprachkonstrukte verwenden darf (z.B. if, case), die außerhalb eines Prozesses nicht erlaubt sind. Und mit diesen Sprachkonstrukten kann man besonders komplizierte Logik viel einfacher beschreiben als mit dem when-Konstrukt. Das ist ein Schwachpunkt von VHDL. ABER: in diesem Fall gehören alle Signale in die SensList, die an der Kombinatorik beteiligt sind. Falls da ein Signal fehlt, erzeugt die Synthese ein unbeabsichtigtes Latch, das führt garantiert zu eine Fehlverhalten Deiner Schaltung und ist für die Timingoptimierung ein Alptraum. Und nein, die SensList spielt keineswegs nur bei der Simulation eine Rolle. Der Inhalt der SensList bestimmt ganz wesentlich das Verhalten der Schaltung auf dem FPGA oder ASIC oder wo auch immer. Ein Änderung an der SensList führt defacto zu einem geänderten Design. Eine saubere Statemachine-Implementierung sieht wie folgt aus: 1. Es gibt einen Prozess, der nichts anderes macht, als den Folgezustand in ein Register zu laden. Die SensList enthält nur den Takt und evtl. einen asynchronen Reset. 2. Bei einfachen Statemachines werden Übergangsfunktion und Ausgangsfunktion ohne Prozess beschrieben. 3. Bei komplizierten FSMs kann man Übergangs- und Ausgangsfunktion auch in einen Prozess packen. Aber dann bitte in einen separaten Prozess und mit vollständiger SensList. Die meisten Lehrbücher für Anfänger verpacken gnadenlos alles in Prozesse, möglichst noch alles in den gleichen Prozess. Das spart ein paar Zeilen, ist aber ansonsten fehleranfällig, irreführend und führt zu schlecht wartbarem Code.
Vancouver schrieb: > Eigentlich hat kombinatorische Logik in einem Prozess überhaupt nichts > zu suchen, da ein VHDL-Prozess ein synchrones Sprachelement ist. Wie kommst du auf diesen abgesägten Ast? > da ein VHDL-Prozess ein synchrones Sprachelement ist. Man kann auch nebenläufig/concurrent ganz einfach ein Schieberegister beschreiben:
1 | schieber <= schieber(6 downto 0) & eingang when rising_edge(clk); |
> Eine saubere Statemachine-Implementierung sieht wie folgt aus: ... Wie gesagt: Ansischtssache. Wozu soll ich mir unbedingt enge Stiefel anziehen und mich in ein unnötiges Korsett zwängen? Man darf das ausnützen, was die Synthesizer können. Ich kann meine Prozesse in der Ein-Prozess-Schreibweise ganz OHNE Sensitivliste recht einfach lesen und warten: http://www.lothar-miller.de/s9y/archives/16-Takt-im-Prozess.html Denn wenn ich gar keine Sensitivliste habe, dann habe ich sicher keine falsche Sensitivliste... http://www.lothar-miller.de/s9y/categories/42-RS232 http://www.lothar-miller.de/s9y/categories/45-SPI-Master
:
Bearbeitet durch Moderator
Vancouver schrieb: > Und nein, die SensList spielt keineswegs nur bei der > Simulation eine Rolle. Der Inhalt der SensList bestimmt ganz wesentlich > das Verhalten der Schaltung auf dem FPGA oder ASIC oder wo auch immer. > Ein Änderung an der SensList führt defacto zu einem geänderten Design. Hast du dafür irgendwelche Belege? Ich habe immer gelernt, dass die Sesitivity List sich nur auf die Simulation auswirkt.
den code kann ich leider nicht posten... Danke schonmal für die vielen Antworten. Ich hab gestern noch gedebuggt und irgendwann ist mir aufgefallen, das das Verhalten ganz logisch war. Vereinfach gesagt:
1 | process(a)... |
2 | a <= a +1; |
Ist ja klar das das nicht funktioniert... Naja, aus solchen Fehlern lernt man am meisten^^ Womit ich aber auf ein neues "Problem" gestossen bin, wo ich grad voll aufm Schlauch stehe... Mein FSM hat a-d zustände. In b) rechne ich einen Wert aus, sagen wir x. in c) benutze ich diesen Wert dann zum weiterrechnen. Wenn ich jetzt eine 2 Prozess darstellung mache passiert im Simulator genau das, das x in der sensitivity List vom Prozess stehen muss, ich also in eine Endlosschleife(im Simulator) reinlaufe... Wie gesagt, ich steh grad voll aufm Schlauch... Ich hätte halt x jetzt in eine variable gepackt, was natürlich zu einem Latch führen muss. Kann man das besser lösen?
:
Bearbeitet durch Moderator
vhdl-anfänger schrieb: > ich also in eine Endlosschleife(im Simulator) reinlaufe... Das ist keine "Endlosschleife", sondern eine "kombinatorische Schleife", die entsteht, wenn die Berechnung von x auch wieder x enthält. Hier wird sowas nicht passieren: x <= a + b; Hier sehr wohl: x <= x + b; Siehe http://www.lothar-miller.de/s9y/archives/42-Kombinatorische-Schleifen.html vhdl-anfänger schrieb: > Wenn ich jetzt eine 2 Prozess darstellung mache passiert im Simulator > genau das Ich hatte das doch schon mal im Beitrag "Re: FSM : Prozess wird genau 2 mal getriggert" verlinkt. Hast du das [ ] nicht gesehen [ ] nicht verstanden
:
Bearbeitet durch Moderator
Lothar M. schrieb: > Hast du das > [x] gesehen > [x] verstanden gesehen und verstanden. Ich hab auch schon überlegt alles in einen Prozess zu schieben. Irgendwie gefällt mir das aber nicht so gut. Ausserdem beantwortet das nicht die Frage, wie man sowas lösen kann, wie ich beschrieben habe.
> Man darf das ausnützen, was die Synthesizer können. Sicher darf man das. Aber das Zauberwörtchen heißt Design Rules. Nicht alles was geht, ist auch sinnvoll, und was asynchron ist, sollte auch asynchron beschrieben werden, oder? Warum musst du unbedingt Kombinatorik in eine synchrone Klammer packen (außer den genannten Gründen) und warum um alles in der Welt schreibst Du ein Schieberegister ohne Prozess? Genau dazu sind Prozesse da. Die meisten Coding Rule Checker werden da mächtig die Augenbraue hochziehen. Ich habe mir das übrigens nicht ausgedacht. Auch die Guides von Xilinx raten von diesen Späßen ab, da sie nicht für eine korrekte Implementierung garantieren können, ebenso die ASIC-Tools soweit ich weiß (die sind aus naheliegenden Gründen noch etwas pingeliger). Die meisten bieten aus diesem Grunde auch Language Templates, deren Benutzung dringenst empfohlen wird. @Dussel: > Hast du dafür irgendwelche Belege? Ich habe immer gelernt, dass die > Sesitivity List sich nur auf die Simulation auswirkt. Ich habe nochmal nachgelesen. Du hast recht, das hatte ich nicht mehr auf dem Schirm, sorry. Tatsächlich ausgewertet wird die SensList nur bei der Simulation. Aber auch die Synthesetools schauen sich die Liste an und versuchen herauszufinden, ob die sinnvoll ist. Wenn das SynTool der Meinung ist, dass z.B. ein Signal fehlt, gibt es eine Warnung, weil dann möglicherweise Synthese und Simulation unterschiedliche Ergebnisse liefern. Dann musst Du Dein Design entsprechend ändern bzw. schauen, ob es mit geänderter SensList noch korrket simuliert. Aber streng genommen hat die SensList keine Auswirkung auf die Synthese, das stimmt. @VHDL_Anfänger: Warum speicherst Du x nicht explizit in einem Register, wenn Deine FSM von b nach c wechselt, und ließt dieses Register in Zustand c wieder aus?
Vancouver schrieb: > @VHDL_Anfänger: > > Warum speicherst Du x nicht explizit in einem Register, wenn Deine FSM > von b nach c wechselt, und ließt dieses Register in Zustand c wieder > aus? Wie gesagt, ich steh grad voll aufm schlauch... Codebeispiel, damit ich mir vorstellen kann was du meinst?
Also, ich gehe davon aus, dass er Zustand deiner FSM in einem signal 'state' gespeichert ist. Die Zustände nenne ich STATE_A, STATE_B usw. -- signalpaar zum Speichern von x signal x_reg, x : std_logic_vector(...); -- wenn die FSM im Zustand STATE_B ist, bekommt x den Wert der Berechnung -- aus STATE_B zugewiesen, ansonsten bleibt der alte Wert von x -- erhalten: x <= result_fom_state_B when (state=STATE_B) else x_reg; -- Speichere den neuen Wert von x in x_reg bei jeder steigenden Taktflanke clockXReg: process (clk) begin if rising_edge(clk) then x_reg <= x; end if; end process clockXReg; Oder wenn Du alles in einem Prozess machen willst: clockXReg: process(clk) begin if rising_edge(clk) then if (state=STATE_B) then x_reg <= result_fom_state_B; end if; end if; end process; In STATE_C kannst Du dann den Wert x_reg verwenden.
Vancouver schrieb: > nd warum um alles in der Welt schreibst Du ein Schieberegister ohne > Prozess? Genau dazu sind Prozesse da. Warum? VHDL kann das schon immer. Nur die Synthesizer konnten das bis ins heutige Jahrtausend so eine Beschreibung nicht umsetzen, weil sie schlicht zu blöd waren. > Die meisten Coding Rule Checker werden da die Augenbraue hochziehen. Dann sind die auch noch nicht fertig. So einfach ist das. Wenn ich schon nicht alle Syntaxelemente synthetisieren kann, dann nutze ich wenigstens die, mit denen es geht, wenn sie mir dadurch den Code lesbarer und wartbarer machen. > Aber auch die Synthesetools schauen sich die Liste an und versuchen > herauszufinden, ob die sinnvoll ist. Wenn das SynTool der Meinung ist, > dass z.B. ein Signal fehlt, gibt es eine Warnung, weil dann > möglicherweise Synthese und Simulation unterschiedliche Ergebnisse > liefern. Wenn ein Signal fehlt, gibt es bestenfalls gerade mal eine Info, dass Simulation und Realität nichtmehr zueinander passen. Vancouver schrieb: > Ich habe mir das übrigens nicht ausgedacht. Auch die Guides von Xilinx > raten von diesen Späßen ab Welcher Guide? > da sie nicht für eine korrekte Implementierung garantieren können Mann muss ganz einfach das Handbuch "seines" Snthesizers lesen. Dort steht drin, was er kann und was nicht. Und in den letzten paar XST Users Guide steht eben drin, dass er es kann... Und zudem sollte man nicht alles glauben, was irgendwer von Xilinx irgendwo geschrieben hat... ;-) Ich verweise mal auf den kapitalen Fehler im Beitrag "Re: Variable vs Signal" > ebenso die ASIC-Tools soweit ich weiß Das ist eine ganz andere Liga mit wesentlich mehr Restriktionen (schon die Taktverteilung und der Reset ist da heikel)...
:
Bearbeitet durch Moderator
Vancouver schrieb: > Also, ich gehe davon aus, dass er Zustand deiner FSM in einem > signal 'state' gespeichert ist. Die Zustände nenne ich STATE_A, > STATE_B usw. > > -- signalpaar zum Speichern von x > signal x_reg, x : std_logic_vector(...); > > -- wenn die FSM im Zustand STATE_B ist, bekommt x den Wert der > Berechnung > -- aus STATE_B zugewiesen, ansonsten bleibt der alte Wert von x > -- erhalten: > x <= result_fom_state_B when (state=STATE_B) else x_reg; > > -- Speichere den neuen Wert von x in x_reg bei jeder steigenden > Taktflanke > clockXReg: process (clk) > begin > if rising_edge(clk) then > x_reg <= x; > end if; > end process clockXReg; > > Oder wenn Du alles in einem Prozess machen willst: > > clockXReg: process(clk) > begin > if rising_edge(clk) then > if (state=STATE_B) then > x_reg <= result_fom_state_B; > end if; > end if; > end process; > > In STATE_C kannst Du dann den Wert x_reg verwenden. Danke für das Bemühen, jetzt weiß ich was du meinst. Ich hab meine FSM jetzt in eine Einprozessdarstellung überführt. Im Nachhinein muss man sagen das ich nicht verstehe warum in so vielen Büchern(oder Tutorials etc.) immer die 2 Prozessdarstellung gewählt wird. Für mich ist das in der 1 Prozessdarstellung - übersichtlicher - einfacher - sicherer(insb. was Latches angeht) auch der Synthetisierer meckert nicht. Ausserdem ist das Ding einfacher zu debuggen, ich glaube auch das es nicht so Fehleranfällig ist. Gibt es irgendwelche Nachteile von der 1 Prozessdarstellung?
vhdl-anfänger schrieb: > Gibt es irgendwelche Nachteile von der 1 Prozessdarstellung? Ja, denn alle Signale in der 1-Prozess-Schreibweise sind ja "registriert", d.h. sie werden durch ein Register implementiert. Damit wird jede Änderung in einem Taktzyklus erst ein Takt später nach Aussen führbar (1 Takt Latenz). In der 2-Prozess-Schreibweise hast du 2 Signale, z.B. a_reg und a_nxt. a_reg ist das Register und a_nxt das im kombinatorischen Prozess generierte Signal (in der 1-Prozess-Schreibweise ist a_reg gleich a). a_nxt ist hier sofort nach Aussen führbar. Ist zwar nicht oft, aber ggf erforderlich. Man muss aber auch wissen, dass man sich damit lange kombinatorische Ausdrücke aufhalst bzw. sogar kombinatorische Schleifen erzeugen kann (Prozess A liesst Signale von Prozess B und umgekehrt). Und bedenken muss man auch, dass die meissten FPGA-Entwickler die 1-Prozess-Schreibweise bevorzugen.
Lothar M. schrieb: >> ebenso die ASIC-Tools soweit ich weiß > Das ist eine ganz andere Liga mit wesentlich mehr Restriktionen (schon > die Taktverteilung und der Reset ist da heikel)... Nun ja, wenn Du auf einem Prototyping-Board mit 4 Virtex7-2000T FPGAs einen SoC-Prototyp entwickelst, dann gewöhnst Du dich am besten gleich an diese Liga. Sonst gibt es ein böses Erwachen gleich bei der ersten ASIC-Synthese. Und diesen Fehler machst Du nur einmal, der Lerneffekt ist hier ganz enorm, glaub mir.
Sigi schrieb: > vhdl-anfänger schrieb: >> Gibt es irgendwelche Nachteile von der 1 Prozessdarstellung? > > Ja, denn alle Signale in der 1-Prozess-Schreibweise > sind ja "registriert", d.h. sie werden durch ein > Register implementiert. Damit wird jede Änderung > in einem Taktzyklus erst ein Takt später nach > Aussen führbar (1 Takt Latenz). > In der 2-Prozess-Schreibweise hast du 2 Signale, > z.B. a_reg und a_nxt. a_reg ist das Register > und a_nxt das im kombinatorischen Prozess > generierte Signal (in der 1-Prozess-Schreibweise > ist a_reg gleich a). a_nxt ist hier sofort nach > Aussen führbar. Ist zwar nicht oft, aber ggf > erforderlich. Man muss aber auch wissen, dass > man sich damit lange kombinatorische Ausdrücke > aufhalst bzw. sogar kombinatorische Schleifen > erzeugen kann (Prozess A liesst Signale von > Prozess B und umgekehrt). > Und bedenken muss man auch, dass die meissten > FPGA-Entwickler die 1-Prozess-Schreibweise > bevorzugen. eben diese kombinatorischen Ausdrücke sind, vor allem wegen der Leserlichkeit, ein Graus... Die wenigen Verenkungen, die ich wegen der 1-clk Latenz machen muss, wiegen, zumindest für meinen fall hier, nicht so schwer wie die verenkungen die ich bei einer 2 prozess darstellung machen muss
Vancouver schrieb: > Nun ja, wenn Du auf einem Prototyping-Board mit 4 Virtex7-2000T FPGAs > einen SoC-Prototyp entwickelst, dann gewöhnst Du dich am besten gleich > an diese Liga Solche Geschosse dürften nur bei den wenigsten FPGA-Entwicklern zum Einstaz kommen.... Wer ASIC machen will (und auch das sind nicht allzu viele) muß tatsächlich diese Restriktionen beachten. Alle anderen dürfen lesbaren/wartbaren Code schreiben. Duke
Vancouver schrieb: > Nun ja, wenn Du auf einem Prototyping-Board mit 4 Virtex7-2000T FPGAs > einen SoC-Prototyp entwickelst, dann gewöhnst Du dich am besten gleich > an diese Liga. Solche Dinger bekommst du sowieso mit nacktem VHDL eh' nicht voll (das wäre ja, wie wenn man versuchen würde, einen Vierkernprozessor mit Assembler niederzuknechten). Da braucht es schon ein paar automatisch generierte Matlab-Modelle und einige Softcores...
Lothar M. schrieb: > das wäre ja, wie wenn man versuchen würde, einen Vierkernprozessor mit > Assembler niederzuknechten). Da braucht es schon ein paar automatisch > generierte Matlab-Modelle und einige Softcores... Stimmt nicht :-) - "Busy-waiting" lässt sich wunderbar in Assembler (und natürlich jeder anderen) Programmiersprache) implementieren - und belegt den Prozessor zuverlässiger mit Vollast als jede Matlab-Simulation - die macht nämlich immer File-I/O und darauf wird per Interrupt gewartet. SCNR, Burkhard
Lothar M. schrieb: > Solche Dinger bekommst du sowieso mit nacktem VHDL eh' nicht voll (das > wäre ja, wie wenn man versuchen würde, einen Vierkernprozessor mit > Assembler niederzuknechten). Da braucht es schon ein paar automatisch > generierte Matlab-Modelle und einige Softcores... Oder eine Datenflussarchitektur, bei der viele parallele Pipelines mit generate-Loops erzeugt werden. Damit geht das recht flott, auch ohne Cores und generierten Code. Und dann treten so Sachen wie mangelnde Routing-Ressourcen, Congestion und nicht erfüllbare Timing-Constraints ans Tageslicht. Den Vergleich mit dem Multicore kann ich aber nicht nachvollziehen. Du kannst jeden Prozessor mit ein paar hundert Zeilen Assemblercode plätten. Fibonacci in 64-Bit Arithmetik oder ein Mersenne-Twister sind da gute Kandidaten. Anscheinend ist die Ansicht Design Rules = schlecht lesbarer bzw. wartbarer Code sehr verbreitet. Ich vermute, ich werde nichts daran ändern können.
Vancouver schrieb: > Du kannst jeden Prozessor mit ein paar hundert Zeilen Assemblercode > plätten. Fibonacci in 64-Bit Arithmetik oder ein Mersenne-Twister > sind da gute Kandidaten. Das sind aber keine Anwendungen in Form von "üblicherweise verwendet". Klar kann man schon den schnellsten Prozessor mit einer einzigen Schleife zum ewigen Inkrementieren eines Registers verdammen. Aber das ist eben genausowenig eine "übliche" Anwendung. > Oder eine Datenflussarchitektur, bei der viele parallele Pipelines mit > generate-Loops erzeugt werden. Damit geht das recht flott, auch ohne > Cores und generierten Code. Auch klar, aber das verwenden eben auch nur recht wenige. Irgendwelche Radar- oder Telekom-Spezis vielleicht. Ein paar Bildverarbeiter dazu, aber dann wird die "High-End"-Luft schnell dünn und die Masse der eingesetzten FPGAs kommt zum Vorschein... Vancouver schrieb: > Anscheinend ist die Ansicht Design Rules = schlecht lesbarer bzw. > wartbarer Code sehr verbreitet. Die Ansicht "wenn Coding Style = letztes Jahrtausend => schlecht lesbar und schlecht wartbar" trifft es eher. Denn "Design Rules" müssen ja weit über den Coding Style hinausgehen. Ein vermurkstes Design wird durch strenge Coding Rules weder zuverlässiger noch besser wartbar.
:
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.