is_x() in Synthese vs. Simulation

OP #7671228
Lesenswert?

Hallo in die Runde,

ich möchte gerne ein X in der Simulation unterdrücken und den selben Code zur Synthese verwenden. Dazu schreibe ich mir ein Modul, welches folgende Funktionalität abbildet:

1
-- Simulation:
2
if is_x(DataIn) then
3
  DataOut <= (others => '0');
4
else
5
  DataOut <= DataIn;
6
end if;
7

8
-- Synthese:
9
  DataOut <= DataIn;

Kann ich das Simulationskonstrukt auch in der Synthese verwenden, ohne dass zusätzliche Logik generiert wird? Ein X gibt es ja in der Hardware nicht.

Alternativ wäre ein If Generate vielleicht eine Option. Wie kann ich für die generate Condition erkennen, ob es sich um eine Simulation oder eine Synthese handelt?

#7671238
Lesenswert?

Leider gibt es keine so richtig gut portable Loesung, aber fuer deinen Fall ist wohl das if .. generate Konstrukt ausreichend, das Setzen der entsprechenden Konfig-Variable wiederum toolabhaengig. Sonst weitere Optionen, die allerdings auch trotz Standardisierungsbemuehungen nicht bei allen Tools gleich funktionieren:

  • VHDL configurations
  • Pragmas ('-- pragma synthesis_off/on', etc.)

Die generate-Variante duerfte die portabelste sein, solange man keine Scherze wie konditionale Einbindung von Modulen bei der Lattice-Toolchain ausprobiert.

Moderator (Firma: Titel) Persönliche Seite #7671241
Lesenswert?

Fpga I. schrieb:

Kann ich das Simulationskonstrukt auch in der Synthese verwenden, ohne dass zusätzliche Logik generiert wird?

Ich würde das einfach mal selber ausprobieren und mir den RTL-Plan und den Ressourcenbedarf ansehen und vergleichen.

Aber ich würde glatt mein Auto drauf wetten, dass der Synthesizer keine Hardware dafür erzeugt.

Ein X gibt es ja in der Hardware nicht.

Ein X gibt es "in der Hardware" schon: das ist eine übliche Buskollision, wenn wzei Teilnehmer gleichzeitig schreibend auf einen Bus zugreifen und der eine ein low, der andere aber ein high treibt.

Aber wenn die "Hardware" ein FPGA ist, dann gibt es da innen drin nur '0' und '1'. Heutige FPGAs haben nicht mal mehr ein 'Z'.

#7671250
Lesenswert?

Lothar M. schrieb:

Aber ich würde glatt mein Auto drauf wetten, dass der Synthesizer keine Hardware dafür erzeugt.

Da gehe ich mit ;-)

Aber die Frage ist, ob die Synthese das 'X' dann als '0' oder '1' ansieht bzw. der Test auf 'X' true oder false ist.

Ich vermute mal letzteres - also false. Aber da es nicht im VHDL-Sprachstandard definiert ist, kann jeder Hersteller das handhaben wie er will.

(Firma: Starfleet) #7671272
Lesenswert?

Aber die Frage ist, ob die Synthese das 'X' dann als '0' oder '1' ansieht bzw. der Test auf 'X' true oder false ist.

Ich vermute mal letzteres - also false.

Eher nicht. Also angenommen ein Treiber trübe Vcc, ein anderer trübe GND - dann ist das Ergebnis Vcc/2, was mit ziemlicher Sicherheit im verbotenen/undefinierten Bereich des Signalstandards gehört.

Mal zum Vergleich der TTL-Standard: https://de.wikipedia.org/wiki/Logikpegel

Man könnte hier auch einen Exkurs in Richtung Metastabilität folgen lassen. https://de.wikipedia.org/wiki/Metastabilit%C3%A4t_(digitale_Schaltung)

#7671286
Lesenswert?

Hä?

Wir sind hier bei der Synthese (und Simulation), nicht beim Betrieb eines FPGAs und schon gar nicht bei Metastabilität und gegeneinander arbeitende Treiber (im FPGA)!

Meine Vermutung, dass die Synthese den Vergleich auf 'X' als false ansieht, beruht einfach darauf, dass 'X' immer ungleich '0' und ungleich '1' ist ;-)

(Firma: Starfleet) #7671294
Lesenswert?

Also nach allgemeinen Verständnis ist gerade die Synthese der Übergang von idealisierten zweiwertigen "Richtig"/"Falsch" Denken in die reale Welt von (analogen/Kontinuirlichen) Spannungen.

Meine Vermutung, dass die Synthese den Vergleich auf 'X' als false ansieht, beruht einfach darauf

Ich vermute, die Synthese bricht mit Fehlermeldung ab, sobald sie auf einen solchen Vergleich im Quelltext trifft.

Halbwegs sinnvoll, wenn auch nicht immer korrekt, wäre noch eine Interpretation als "don't care". Siehe Anhang (aus: http://www.gstitt.ece.ufl.edu/courses/spring10/eel4712/lectures/vhdl/xst.pdf)

Für Vivado: https://support.xilinx.com/s/article/64042?language=en_US -> für vivado synthese vermeide 'X' und 'U' in Vergleichen

Angehängte Dateien:
#7671313
Lesenswert?

Bradward B. schrieb:

Ich vermute, die Synthese bricht mit Fehlermeldung ab, sobald sie auf einen solchen Vergleich im Quelltext trifft.

Nein, tut sie nicht - gerade mit Synplify getestet. Warum sollte sie auch? 'X' ist immer ungleich '0' oder '1'.

Außerdem ist es zulässig, Konstanten (std_logic) mit 'X', 'Z', 'H', 'L' usw. zu definieren und im weiteren Quelltext diese zu vergleichen (und entsprechende unterschiedliche Aktionen zu bewirken). Und warum sollte das nicht auch bei Signalen möglich sein?

Einzig der Verleich von Was-auch-immer auf '-' (don't care) könnte die Synthese sinnvoll als true betrachten.

(Firma: Starfleet) #7671324
Lesenswert?

Einzig der Verleich von Was-auch-immer auf '-' (don't care) könnte die Synthese sinnvoll als true betrachten.

Dont care ist mit 'X' und mit '-' assoziiert(siehe Anhang oben). Und Dont'care ist weder explizit "true" oder "false". Wobei true and false doch eher vom type boolean ist, während 'X' zur neunwertige Logic std_logic aka IEEE-1164 gehört.

Nein, tut sie nicht - gerade mit Synplify getestet

Synplify nist eines von vielen Synthesetools, da gibt es keinen herstellerübergreifenden Standard. Schon bei unterschiedlichen synthesetargets/Architekturen kann man unterschiedliche Ergebnisse erreichen.

(Firma: Starfleet) #7671357
Lesenswert?

Pat A. schrieb:

Bradward B. schrieb:

Dont care ist aber mit 'X' definiert

Das macht Xilix ganz willkürlich bei XST so. Ob das Vivado oder Synplify auch so handhaben, steht auf einem ganz anderen (Daten-) Blatt.

Auf das "Blatt" von Vivado wurde bereits verwiesen, bei Vivado wird empfohlen auf 'X' bei Comperatoren zu verzichten um eben die Mehrdeutigkeiten von don't care zu vermeiden.

Und Dont'care ist weder explizit "true" oder "false"

Habe ich weder geschrieben noch behauptet.

Naja, da wird ziemlich oft Dont'care in einem Atemzug mit "true" und "false" genannt, obwohl "true" und "false" in VHDL zum enum typ boolean gehören und "X" und "-" dagegen zum enum type std_logic. Und std_logic gehört genau genommen nicht zum selben standard wie VHDL mit boolean (IEEE-1076) sondern wurzelt in einem eigenen (IEEE-1164).

#7671373
Lesenswert?

Bradward B. schrieb:

Naja, da wird ziemlich oft Dont'care in einem Atemzug mit "true" und "false" genannt

Sind meine Sätze zu lang bzw. zu kompliziert für Dich? Ok, dann mal als Essenz: "Ein Test/Vergleich von ... ergibt true bzw. false."

Und sei Dir sicher, 'boolean' und 'std_logic' kann ich gerade so schon unterscheiden, obwohl ich VHDL erst seit gestern mache ;-)

So, das wars für mich hier, ich bin dann mal raus. Die Lösung für den TO steht schon im 2. und 3. Beitrag.

Noch ein schönes Wochenende!

(Firma: Starfleet) #7671397
Lesenswert?

So, das wars für mich hier, ich bin dann mal raus. Die Lösung für den TO steht schon im 2. und 3. Beitrag.

Der 3. Beitrag enthält (Hersteller-) proprietäre Schlüsselworte und ist somit als allgemeine Lösung untauglich.

https://insights.sigasi.com/tech/list-known-vhdl-metacomment-pragmas/

Und der zweite Beitrag wiederholt im wesentlich den "workaround" den der TO selbst vorgeschlagen hat und verweist im weiteren darauf, das es keine allgemeine Lösung gibt.

#7671402
Lesenswert?

Mal unabhängig von irgendwelchen Standards und wie sie von den Toolherstellern interpretiert werden: Das Codebeispiel des TO hat in der Simulation ein anderes Verhalten als in der realen Hardware. Das ist schon mal ganz schlechter Style. Ein undefinierter Signalszustand darf in einem korrekten Design keinen Einfluss auf das Ergebnis haben, weil das sonst indeterministisch wird. Insbesondere kann ein solcher X-Zustand nicht verwendet werden, um damit einen Multiplexer zu steuern, weil eine digitales Design einfach nicht in der Lage ist, ein X als solches zu erkennen. Es ist daher sinnvoll, is_x() währnd der Synthese grundsätzlich als false anzunehmen und wegzuoptimieren, und der Großteil der Tool macht das auch so (und gibt zumindest eine Warnung aus). Aber die saubere Lösung ist, eindeutig zwischen Synthese- und Simulationskontext zu unterscheiden, sprich die schon vorgeschlagene Lösung mit einem GENERATE-Konstrukt (bzw. ifdef in Verilog). Da die Syntesetools dann das is_x() gar nicht zu sehen bekommen, ist die Bedeutung des Codes eindeutig- sowohl für die Tools als auch denjenigen, der den Code lesen und verstehen muss. Es gilt auch hier: Eindeutigkeit zum Preis von ein paar mehr Lines of Code ist mehr Wert als freakige Shortcuts mit situationsabhängiger Semantik. Das steht in der Einleitung von so ziemlich jedem brauchbaren Styleguide.

OP #7672868
Lesenswert?

Dank Euch für Euren Antworten.

Noch ein kleiner Hintergrund, wie das X zustande kommt: Es wird immer nur ein Teil eines Blockrams geschrieben und anschließend der volle Inhalt de Blockrams versendet (incl. CRC Berechnung über BRAM Inhalt). Protokolltechnisch erkennt der Empfänger, wo das Ende der genutzten Bytes innerhalb der Nachricht ist, sodass der hintere Teil ein "Don't Care" ist. Lediglich die CRC wird über die volle Nachricht berechnet. Ist das Blockram nicht initialisiert, liest die Simulation ein X zurück, während das FPGA dort typischer Weise eine '0' stehen hat (genaueres findet sich im Datenblatt der zugehörigen Bausteinfamilie). Aufgrund der Verwendung generischer vorhandener Module kann das Blockram nicht initialisiert werden (in anderen Kontexten möchte ich das X gerne sehen, um in der Simulation gleich darüber zu stolpern, wenn ich zu viel aus dem RAM lese). Damit ich eine CRC sowohl sendeseitig als auch empfangsseitig berechnen kann, darf in der Simulation also kein X aus dem Blockram kommen.

Ich habe nun die passenden Lösungsansätze an der Hand und werde noch mal kurz in mich gehen und dann eine Variante auswählen. D

(Firma: Starfleet) #7672966
Lesenswert?

Fpga I. schrieb:

Dank Euch für Euren Antworten.

Noch ein kleiner Hintergrund, wie das X zustande kommt: Protokolltechnisch erkennt der Empfänger, wo das Ende der genutzten Bytes innerhalb der Nachricht ist, sodass der hintere Teil ein "Don't Care" ist. Lediglich die CRC wird über die volle Nachricht berechnet. Ist das Blockram nicht initialisiert, liest die Simulation ein X zurück, während das FPGA dort typischer Weise eine '0' stehen hat (genaueres findet sich im Datenblatt der zugehörigen Bausteinfamilie).

Also in Echt würde dort eine '0' stehen aber wegen "suboptimal" aufgesetzter Simulation bringt das Model ein 'X' (BTW, ein X steht nicht für "don't care" sondern für "Unknown" und bei Unitialisiert wäre eigentlich ein 'U' gefordert https://en.wikipedia.org/wiki/IEEE_1164 ) ???

IMHO ist das die Ursache des Problems an dem man sinnvollerweise eine Lösung ansetzen sollte. Und AFAIK gibt es für jeden BlockRAM eine Möglichkeit der Initialisierung, da man diesen BRAM auch als ROM einsetzen könnte. Also einfach ein korrektes Model des BRAM benutzen/anfordern, möglicherweise liegt es nur an einem suboptimal gesetzten Haken bei der Source-Generierung.

Anbei ein Auszug diesbezüglich für die Xilinx series-7 Familie. Wenn genannt würde, welche Familie konkret eingesetzt wird, könnte man das natürlih auch raussuchen.

Angehängte Dateien:
OP #7683913
Lesenswert?

Ich beschreibe mein RAM in VHDL. Die Initialisierung des BRam wäre technisch problemlos möglich, ist aber nicht gewünscht: Ich ein generisches Memory Modul, welches mir u.a. ein double buffering implementiert. Da das Modul auch in anderen Projekten zum Einsatz kommt, möchte ich das BRam nicht initialisieren, da es normalerweise ja ein Fehler ist, wenn ich Daten lese, die zuvor nicht geschrieben wurden. In sofern hat das X in der Simulation schon seine Berechtigung und soll gerne sichtbar bleiben. Das aktuelle Projekt bildet ist eine Ausnahme, dort ist es ok, Werte zu lesen und weiter zu verarbeiten, die nie geschrieben wurden.

Ich habe mir übrigens mit einem Modul beholfen, welches ich hinter die BRam ReadData hänge. Es enthält eine einzige Concurrent Anweisung: o_DataOut <= to_01(i_DataIn);

P.S.: Ob in der Simulation dort ein X oder U stand, weiß ich nicht mehr, vermutlich ein U, aber beides wird ja durch die Funktion is_x() abgefangen

(Firma: Starfleet) #7683925
Lesenswert?

Fpga I. schrieb:

Da das Modul auch in anderen Projekten zum Einsatz kommt, möchte ich das BRam nicht initialisieren, da es normalerweise ja ein Fehler ist, wenn ich Daten lese, die zuvor nicht geschrieben wurden. In sofern hat das X in der Simulation schon seine Berechtigung und soll gerne sichtbar bleiben.

Für jedes "Fehler-szenario" sollte man ein eigenen Check im Simulationsmodel haben. Hier habe ich den Eindruck, das drei verschiedene Szenarien mit dem selben abgedeckt Test werden sollen:

  • Speicherfeld ist nicht initialisiert
  • Lesen einer Speicherstelle die nicht vorher beschrieben wurde
  • mehrer Signalsender treiben gleichzeitig eine Signalleitung.

Das dritte wird IMHO durch ein 'X' angezeigt, ersteres 'U'. Natürlich ist es bei der dritten variante wichtig, ob ein Typ mit resolution function ('std_logic') oder ohne ('std_ulogic') benutzt.

https://tams.informatik.uni-hamburg.de/applets/hades/webdemos/00-intro/03-stdlogic/resolution.html

Das zweite -read without write- wird durch einen Test im Speicher-modell selbst abgefangen, respektive bei der Simulation gabs eine warning/report (VHDL-assert) im log.

Der ersten Fall (nicht-initialisierung) könnte/sollte wo nötig (Parameter-file/ROM) zu einem Test auf richtige Init-Datensatz erweitert sein. Das macht aber auch gerne die Software beim PowerUp-Test selbst, sie prüft ob zu Softwareversion passende Parameter-daten vorhanden sind.

#7684169
Lesenswert?

Bradward B. schrieb:

  • mehrer Signalsender treiben gleichzeitig eine Signalleitung.

Das dritte wird IMHO durch ein 'X' angezeigt, ersteres 'U'. Natürlich ist es bei der dritten variante wichtig, ob ein Typ mit resolution function ('std_logic') oder ohne ('std_ulogic') benutzt.

Ein 'X' kommt auch z.b. durch arithmetische Operationen von uninitialisierten Werten zustande. Mal ganz abgesehen vom RAM-Modell, welches auch in gewissen Szenarien ein 'X' aktiv schmeissen koennte. Da die TDP-Modelle mit ihren unzaehligen Konfigurationsmoeglichkeiten einiges an Kombinatorik bereithalten, kommt da schon mal ein 'U' als ein 'X' raus.

Dann kommen noch Unterschiede zwischen VHDL93 und VHDL08 dazu, die nicht ueberall korrekt nach Standard abgefertigt werden. Da zeigte Xsim in der Vergangenheit auch mal was anderes an als GHDL.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren