Forum: FPGA, VHDL & Co. Verhalten von IOs bei Simulationen


von Bernd G. (Gast)


Lesenswert?

Wir sind auf folgendes Problem gestoßen:

Ein Bussystem aus Microcontrollern, FPGA und einigen Security-Chips soll 
funktionell simuliert werden. Dabei gibt es aber einige IOs am FPGA die 
per constraint auf pullup und pulldown gesetzt sind und auch so 
funktionieren. In den Stimulidateien vom Hersteller verhalten sich die 
Chips entsprechend, setzen ihre Leitungen auf high, lo und high-Z.

Sofern die Leitungen durch die Simulationszustände getrieben werden, 
funktioniert alles. Bei high-Z arbeitet aber die FPGA-Schaltung nicht 
richtig, weil sie keinen verwertbaren Zustand erhält. In der Realität 
würde der pull-Widerstand den Pegel herstellen, den gibt es aber in der 
Simulation nicht. Bei I2C ist das z.B. kein Problem, weil die Modelle 
der Leitungen einen R vorgesehen haben und am Ausgang nur 1 und 0 
anliefern. An den Stellen, wo wir das selber gemacht haben, sitzt ein 
manueller Widerstand, der die Leitung auf 1 zieht.

Muss man jetzt alle FPGA-Ausgänge händisch nachversorgen, oder gibt es 
da einen automatischen Weg?

von Lars (rezyy)


Lesenswert?

Bernd schrieb:
> Bei high-Z arbeitet aber die FPGA-Schaltung nicht
> richtig, weil sie keinen verwertbaren Zustand erhält.

Ich sehe euer konkretes Problem noch nicht. Weshalb arbeitet das Design 
denn nicht richtig? Ein korrektes Design sollte in der Simulation nur 
richtige Flanken von (rising bspw. '0'/'L' auf '1'/'H') als gültig 
ansehen.

Bei solchen Problemen habe ich grundsätzlich folgendes im Kopf: Welches 
Konstrukt für die FFs nutzt ihr für euer Design?
1
clk'event and clk = '1'
oder
1
rising_edge(clk)

Im zweiten Fall sollten solche Simulationen korrekt laufen, im ersten 
Fall würde die Simulation auch Flanken erkennen, die bspw. von HIGH-Z/Hi 
auf '1' gezogen werden - das kann zu fehlerhaften Simulationen führen.

Ist das vielleicht schon euer Problem? Ansonsten könnt ihr in eurer 
Testbench den Pullup/down aufm Bus mit einbauen..

Allgemein gilt halt: Nutzt lieber rising_edge() in Designs. Dieses 
veraltete clk'event-Zeug geistert noch immer viel rum und kann bei 
Simulationen eben Probleme verursachen..

von J. S. (engineer) Benutzerseite


Lesenswert?

L. schrieb:
> Dieses
> veraltete clk'event-Zeug geistert noch immer viel rum und kann bei
> Simulationen eben Probleme verursachen..

Dazu muss aber gesagt werden, dass man nur mit dem "clk'event-Zeug" alle 
möglichen Fälle und Kombinationen des Aufeinandertreffens von 
physikalischen Zuständen einer Leitung abbilden kann und um die scheint 
es ja hier zu gehen, wenn ich da was von "Z" lese.

Generell sollte man Logik-Simulation von Physik-Simulation trennen. Mit 
VHDL geht ja beides, weswegen man ja zwischen Logikpegeln 0, 1 und U 
sowie physischen Pegeln L, H und X sowie weak und anderen unterscheidet. 
Das wird leider heute kaum noch gemacht oder gelehrt, weil alle nur noch 
Logik bauen und dem Tool die Implementierung in hardware überlassen. 
Daher wird dann viel vermengt und vermischt, was die Simulationen 
unnötig erschwert.

Sofern es eine reine Logiksimuation ist, also mit 0 und 1 innnerhalb der 
Schaltung, reicht rising_edge und es braucht weder L noch H etc. Da hat 
es ja auch nur eine Signalrichtung von Signalquelle zu Empfänger.

Wenn aber Elektronik simuliert werden soll, kann es mehrere Sender und 
Empfänger geben, weil die VHDL-Signale keine logischen Ereignisse mehr 
sind, sondern quasi Leitungen. Entsprechend sind die Kollisionen und das 
Zeitverhalten zu betrachten. Hier wird wahrscheinlich ein weak pull up 
an den inputs reichen.

Meines Erachtens hat man es bei der Definition von VHDL verbummelt, 
zwischen Logiksignalen und Drähten zu unterscheiden, vermutlich deshalb, 
weil die ersten Bausteine und Chips durchaus bidirektionale Leitungen 
hatten und nicht zwangsläufig aus einem abstrakten Logikdesign erzeugt 
wurden, wie wir es heute kennen. Hätte man das getan, würde man einen 
echten Informationsübergang mit Zuordnung der beiden Domänen beschreiben 
müssen und auch können, was bei solchen rücklesbaren FPGA-IO eh 
vorteilhaft wäre und in den Logikdesigns dieser Welt gäbe es so einen 
Quark wie "low aktive Signale" nicht, weil einer Physik tief ins Design 
gezogen hat, wie man es bei Xilinx oft findet.

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

J. S. schrieb:
> Sofern es eine reine Logiksimuation ist, also mit 0 und 1 innnerhalb der
> Schaltung, reicht rising_edge und es braucht weder L noch H etc.

L. schrieb:
> Ein korrektes Design sollte in der Simulation nur
> richtige Flanken von (rising bspw. '0'/'L' auf '1'/'H') als gültig
> ansehen.

Und genau so ist das auch. rising_edge() deckt '0' -> '1', '0' -> 'H', 
'L' -> 'H' und 'L' -> '1' ab.

https://www2.cs.sfu.ca/~ggbaker/reference/std_logic/1164/rising_edge.html
1
  function rising_edge (signal s : STD_ULOGIC) return BOOLEAN is
2
  begin
3
    return (s'event and (To_X01(s) = '1') and
4
            (To_X01(s'last_value) = '0'));
5
  end rising_edge;
6
7
  function falling_edge (signal s : STD_ULOGIC) return BOOLEAN is
8
  begin
9
    return (s'event and (To_X01(s) = '0') and
10
            (To_X01(s'last_value) = '1'));
11
  end falling_edge;

: Bearbeitet durch User
von J. S. (engineer) Benutzerseite


Lesenswert?

Gustl B. schrieb:
> Und genau so ist das auch. rising_edge() deckt '0' -> '1', '0' -> 'H',
> 'L' -> 'H' und 'L' -> '1' ab.

Ja und das ist z.B. dann falsch, wenn man Elektroniken simulieren will, 
wie in PMOS, bei denen LO nämlich 1 ist. Es wird nämlich fälschlich 
Logik mit Physik verwechselt und eindimensional 0 immer mit L 
gleichgesetzt.

"rising_edge" ist ein Logikkonstrukt und beschreibt den infinitismalen 
Zeitpunkt eines Logikpegelübergangs. Wohlgemerkt einen Zeitpunkt und 
zwar einen in einem getakteten Design. Das ist ein Stück Information. 
Dort hat Physik mit Lo und HI nichts zu suchen. Sie werden dort weder 
gebraucht noch kann man 0 und LO überhaupt vergleichen. Es wird 
unrichtigerweise vermischt.

: Bearbeitet durch User
von Superbus (Gast)


Lesenswert?

(1) lerne endlich mal FPGA von der Picke aufoder stelle jemanden ein, 
der das mal gelernt hat.

Falls in deiner Schaltung ein PullUp vorkommt, muss du den natürlich 
auch in der Simulationsumgebung simulieren. Also ein 'H' dem Bus 
std_logic_vector zuweisen.
Oder Du instanziierst einen PullUp, oder du verwendest eine Instanz des 
IO-Pads....

https://docs.xilinx.com/r/en-US/ug953-vivado-7series-libraries/IOBUF
https://docs.xilinx.com/r/en-US/ug953-vivado-7series-libraries/PULLDOWN
https://groups.google.com/g/comp.lang.vhdl/c/rj1DzSTOWA0
https://www.itiv.kit.edu/747.php

==

Und wegen der verzickten Forumssoftware hier die Antwort auf einen 
anderen thread

Bernd schrieb:

> In VHDL ist es so, dass mehr hardware angefordert wird, die meines
> Wissens bei der Synthesumsetzung wieder zusammenfällt, weil Redundanz
> eliminiert werden sollte.

Sorry aber bei diesem "Satz" überfiel mich ein spontaner Kotzreiz und 
ich musste mir erstmal ne neue Tastatur besorgen.

(1) lerne endlich mal FPGA von der Picke auf oder stelle jemanden ein,
der das mal gelernt hat.

State Maschine und deren Implementierung ist in Embedded C und in FPGA 
nicht dasselbe. Wo das C-Codierschwein eine state machine zur 
Protokoll-/Ablauf-steuerung/codierung sagt, verwendet man im FPGA eher 
einen "sequenzer" der prior nachgeordnete FSM anstösst, die wiederum 
data path umschalten.

Bei den Abfragen auf die Maschinencodierung kommt es darauf an, ob diese 
Abfrage zur Compile- oder zur Laufzeit ausgeführt wird. Ersteres kann 
unter Umstanden automatisch bei der Code-übersetzung entfernt werden, 
wenn "dead code elimination" aktiv ist. Natürlich sollte auf "area" 
optimiert werden und bei einer "umfänglichen" aka vom C-Codierheini 
unnötig aufgeblähten" FSM ist eine one-hot" Codierung eher 
kontraproduktiv, da passt besser "binary".

Und macht dir mal Gedanken was "Modulares Design" bedeutet und wie in 
diesem Zusammenhang die Konzepte "HAL" und device driver genutzt werden.

Für eine saubere Umschaltung zwischen maschinenspez. Varianten muss man 
saubere Schnittstellen/Interface einführen und nicht irgendwo "Abfragen" 
in die Codebasis einstreuen .

von Bernd G. (Gast)


Lesenswert?

Warum postest du alles zweimal?
Was deine Magenproblem angeht, habe ich bereits im anderen thread 
geantwortet.

von Bernd G. (Gast)


Lesenswert?

Superbus schrieb:
> Falls in deiner Schaltung ein PullUp vorkommt, muss du den natürlich
> auch in der Simulationsumgebung simulieren.

In der Schaltung kommt er nicht vor. Er steckt in der 
FPGA-Spezifikation, konkret im constraint, wird also erst bei der 
Implementierung aktiv.

Der Simulator sieht diesen Pullup nicht.

von Rick D. (rickdangerus)


Lesenswert?

Bernd G. schrieb:
> Der Simulator sieht diesen Pullup nicht.
Prima!
Wenn man will, das Simulation und Realität in Einklang sind, sollte man 
dafür sorgen, das die relevanten Parameter passen.

Also spendiere einfach deiner Simulation einen Pullup:
1
  mein_signal_in_der_testbench_mit_pullup  <= 'H';

von A. F. (chefdesigner)


Lesenswert?

Rick D. schrieb:
> Also spendiere einfach deiner Simulation einen Pullup:
> mein_signal_in_der_testbench_mit_pullup  <= 'H';

Geht das so einfach, ohne Kollision?
Laut GG muss dann aber der Code angepasst werden:
https://groups.google.com/g/comp.lang.vhdl/c/rj1DzSTOWA0

von Markus F. (mfro)


Lesenswert?

Andi F. schrieb:
> Laut GG

Grundgesetz? Gustav Gans?

Ohnespass: das geht so einfach.
Vorausgesetzt dein Signal ist ein resolved type.

von A. F. (chefdesigner)


Lesenswert?

Markus F. schrieb:
> Grundgesetz? Gustav Gans?
Google Groups - wie im link benannt.

von J. S. (engineer) Benutzerseite


Lesenswert?

Rick D. schrieb:
> Also spendiere einfach deiner Simulation einen Pullup:

Man kann das über die libraries lösen, aber das ist trotzdem unklug bis 
ungeschick! Das Abprüfen von allenmöglichen theoretischen Kombinationen, 
die einen Takt auslösen können sollen, bläht die Simulation auf und 
macht sie unnötig kompliziert und langsam.

Ich trenne konsequent die Physik von der Logilk, denn zu 95% wird die 
Physik beim Verifizieren ja nicht benötigt. Wenn externe Elektronik 
mitsimuliert werde soll, müssen eben die echten IOs, respektive 
Ersatzmodelle eingebunden werden. Deren Verhalten kann man dann im 
Detail mit eventuellen Schaltverzögerung simulieren, inklusive von 
möglichen Fehlern infolge äußerer Einflüsse, wie ich das schon machen 
musste.

Man braucht dann einen IO-Pin der den Kontaktpunkt zur Leiterplatte 
simuliert und von 2 Seiten Informationen verarbeiten kann und diese auch 
abgibt. Wenn z.B. ein Pullup spezifiziert ist, wird man die Leitung bei 
Z auf 1 ziehen und ansonsten den Zustand des dominanten Signals. 
Kollidiert das, kriegt der Ausgang U, was hilft, Information zu 
verarbeiten, die kurzzeitig unsicher ist, wie z.B. eine solche 
I2C-Leitung. Da gibt es ja regelmässig Problem mit dem ACK, wenn der 
FPGA zu schnell ist.

Wird eine Leitung aktiv kurzgeschlossen, gibt es in X und einen Fehler 
mit Assert.

Mit getrenten Ein- und Ausgängen in beide Richtungen kann man sehr gut 
die Inputs und Outputs im FPGA betreiben, d.h. der Output nimmt das an, 
was der FPGA sagt und dessen Input wiederum das, was die Leitung sagt.

Literatur: "Digital Electronics with VHDL" Quartus-Edition Pearson

Wie gesagt ist das aber alles nur im Rahmen von physikalischer Simulatio 
nötig. Für die logische Schaltfunktion lässt man am Besten alles an IOs, 
PLLs und Timing aus der Simulation raus. Dann kann der Compiler das auch 
sinnvoll kleinkomprimieren.

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
Noch kein Account? Hier anmelden.