Hallo,
vielleicht stehe ich nur auf dem Schlauch, aber ich dachte ich frage mal
in die Runde.
Ich möchte einen Pin mit externem Pullup simulieren.
Dabei kann der externe Baustein für ein Busy die Leitung auf 0 ziehen.
(Außerdem kann er noch Daten schicken, aber das ist hier egal)
D.h. ich muss intern auf 'Z' setzen und '1' prüfen, d.h. ob nicht busy.
Soweit, so gut.
Ich muss aber auch auf der Gegenstelle das gleiche tun, d.h. in der
Testbench auf 'z' oder 'H' setzen um zu lauschen was das FPGA so
schickt.
D.h. bei nicht busy kann ich nicht einfach '1' von der testbench
treiben.
Aktuell sieht mein Code so aus(Codebeispiel, nur relevanter Teil)
TB
Variante 2 funktioniert für die Simulation. Klar, weil 'H' eben nicht
'0' ist kann ich damit arbeiten.
Ich habe aber ein schlechtes Gewissen für die Synthese, dort würde ich
lieber Variante 1 nehmen. Die bekomme ich aber wie gesagt nicht
simuliert, weil die TB ein H treibt.
Was tun?
Und damit käme zumindest mal der Vivado-Synthesizer gut zurecht, weil er
naheliegenderweise 'H' wie '1' behandelt. Jetzt musst du nur noch das
Handbuch deines Synthesizers lesen, um dort die selbe Passage zu
finden...
Mensch Lothar, was du alles ausgräbst :)
Für Quartus habe ich auf die schnelle nichts gefunden, aber ich werde
nochmal auf die Suche gehen.
Hatte die Hoffnung es gibt eventuell eine elegantere Lösung, die
eindeutiger ist, ohne vom Tool abhängig zu sein.
Natürlich ist man das immer ein bischen, aber ein Vergleich auf '1' wäre
in der Hinsicht schon nett.
FPGA zum Spass schrieb im Beitrag #5861051:
> aber ein Vergleich auf '1' wäre in der Hinsicht schon nett.
Dann musst du ein to_01() aus der numeric_std dazupacken:
Wieder mal ein nettes Beispiel dafür, dass es wichtig ist, physikalische
Simulationen mit VHDL getrennt von den logischen durchzuführen und das
Logikdesign von der äusseren Physik zu trennen. Dann ergeben sich solche
Überschneidungen gar nicht. In der P-Simulation braucht man dann nur
einen Überwacher, der bei einen unbelegten Signal, das nicht vom FPGA
und nicht von irgendeinen anderen Bausteing getrieben wird, eine 1 zu
setzen. Die konsequente Trennung von äuserer Leitung (linke Seite des
Pins) und der inneren Leitung (rechte Seite des Pins) ermöglicht diesen
Zugriff und die Beobachtung der informationsgebenden Signale. Das geht
auch und vor allem durch die Tristate-Buffer durch und schafft ein
tatsächliches Zeitverhalten, dessen eleganter Nebeneffekt es ist, dass
die Simulation nicht in eine Schleife rennt, wenn man die Reaktion des
Pins mit einigen ps verzögert. Danm kann man sich meist auch das
umständliche Simulieren der buffer-Verzögerungen mit exakten Timings
sparen. Die Reaktionen der Chips auf die Signale sind dann immer
sequentiell wie in der Realität.
Danke Lothar, genau sowas habe ich gesucht.
Sehr fein.
Ich teste dann morgen ob das auch "synthesefest" ist, für heute ist
Schluss.
@ Jürgen:
sind das jetzt threoretische Überlegungen oder kannst du konkret
beschreiben was du da meinst?
FPGA zum Spass schrieb im Beitrag #5861131:
> sind das jetzt threoretische Überlegungen oder kannst du konkret> beschreiben was du da meinst?
Das ist durchaus sehr praktisch gemeint.
Bei der Simulation der Interaktion des FPGAs mit seiner Umgebung
simuliert man ja Interfaces zu Prozessoren, das Verhalten von
Leitungstreibern und/oder die Kommunikation über PCB-Grenzen hinweg mit
anderen Teilnehmern. Oft kommt es auch auf die Interaktion von
Baugruppen an, wenn sie am selben Bus hängen, sei es ein bidirektionaler
Datenbus, I2C oder sonst etwas.
Bei diesen Simulation gibt es nicht nur völlig andere Zielsetzungen und
damit Testcases, sondern auch ein völlig andere Timing, komplett
losgelöst von FPGA-Takten. Daher sollte man das auch isoliert
voneinander abwickeln. Z.B. braucht man hier mitunter die min/max Zeiten
von irgendwelchen Buffern, also Exemplarstreuungen.
Hat man das im Griff, kann man sich bei der Interaktion von z.B.
Prozessor und FPGA sowie allen Innereien auf die Logiksimulation
beschränken.
Die Frage ist ja immer wieviel Aufwand man treiben will und muss.
Fürs Hobby reicht mir z.b. wenn etwas bei Raumtemperatur auf meinem
Evalboard funktioniert.
Für eine Massenproduktion muss ich ggf sogar während der Laufzeit
Timings überwachen, also das andere Ende des Spektrums.
Hierfür passt das alles aber weniger, weil es um einen halbwegs
langsamen Bus geht und ich eigentlich nur die Logikseite brauche und
dafür eben einen Pullup in der Simulation.
Habe es jetzt übrigens so gelöst:
1
if(to_bit(signal_in)='1')then-- Variante 5
weil entwerder steht ich auf dem Schlauch oder to_01 von der numeric_std
kann nur signed und unsigned konvertieren, ich habe jedoch einen
std_logic.
Läuft jedenfalls in Simulation und Synthese und sieht halbwegs sauber
aus.
>> Das finde ich noch besser,
Ich schreibe in diesen Faellen die Logik immer um und pruefe auf '0'.
1
if(signal_in='0')then
2
...
3
else
4
...
Das finde ich immer ganz gut lesbar, auch weil das 0 ziehen aktiv
geschieht, waehrend die '1'/'H' nur einer Art idle Zustand entspricht.
Ist das wirklich mal unguenstig, dann eignet sich auch eine vorherige
Konvertierung auf kombinatorischer Ebene
1
sig<='0'whensignal_in='0'else'1';
2
3
-- ab dann mit sig weiterarbeiten wie gewohnt
Das finde ich einfach sauberer und sollte mit praktisch allen Synthese
Werkzeugen kompatibel sein, da die Pruefung auf 'H' komplett entfaellt.
Eine eigene Frage?
Dieser Thread ist über 7 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.