Hintergrund
Ich entwerfe eine Schnittstelle in VHDL, die eine Verbindung zu einem bidirektionalen Signal herstellt. Meine Erfahrung in der Dynamik des Hardware-Designs ist jedoch begrenzt. Was ich im Moment habe, ist unten:
Innerhalb der roten Box befindet sich das FPGA, außerhalb befinden sich elektrische Komponenten.
Das RX-Modul sucht nach einem LOW-Signal für ein Startbit. Um Interferenzen zwischen dem TX-Modul und dem RX-Modul zu vermeiden: Ich habe einen Mux platziert, der vom TX-Modul gesteuert wird, um HIGH zu passieren, wenn es sendet.
Die externe Schaltung stellt sicher, dass mein TX die Leitung niemals auf HIGH treibt, um Kurzschlüsse zu vermeiden.
Das Problem
Wenn die RX- und TX-Module getrennt sind, funktionieren sie perfekt. Der RX empfängt und liest das Signal richtig und der TX sendet (nicht in die bidirektionale Leitung; stattdessen: mein Oszilloskop) perfekt. Den Schalter zu schließen, um die beiden zu kombinieren, ist jedoch eine Katastrophe. Das RX-Modul scheint einfach nicht mehr zu reagieren.
Die Frage
Ich bin mir nicht sicher, ob dies ein allgemeines Designproblem oder etwas Kleines und Dummes mit meinem VHDL ist.
Ist dies also eine akzeptable Methode für die Anbindung an ein bidirektionales Signal? Ich habe das Gefühl, dass mit meiner Einstellung etwas nicht stimmt. Ich suche nur nach Vorschlägen, Kritik oder allgemeinen Ideen.
Wenn dies tatsächlich ein gutes Setup ist, dann kann ich zumindest zuversichtlich sein, das VHDL selbst auf das Problem hin zu untersuchen, und zu wissen, dass meine Bemühungen aufgrund eines inhärent fehlerhaften Gesamtdesigns nicht umsonst sein werden.
Googeln: "Schnittstelle zu einem bidirektionalen Bus" scheint Tri-State-Puffer vorzuschlagen. Ist das ein besserer Ansatz?
Extra
Ich fühle mich unausstehlich, euch wegen mangelndem konzeptionellen Verständnis ständig zu nerven. Wenn ich also einen Vorschlag zu Büchern oder verschiedenen Forschungsquellen für das konzeptionelle Entwerfen von Hardware bekommen könnte, wäre das fantastisch.
Tristate ist, was Sie wollen. Oder, da Sie einen externen Pull-up-Widerstand haben, ein Open-Drain- Laufwerk. Sie werden auch sehen, dass Open-Collector dasselbe bedeutet - es hängt von der Art der verwendeten Transistoren ab, aber die grundlegende Idee ist dieselbe. ISO9141 (Kfz-Diagnose) arbeitet beispielsweise so.
Open-Drain bedeutet nur, dass der Treiberstift das externe Signal nur auf Low ziehen, aber nicht auf High treiben kann - der Widerstand lässt die Leitung sanft wieder nach oben "schweben". Es bedeutet auch, dass mehrere Geräte die Kommunikationsleitung steuern können, sodass Sie sicherstellen müssen (z. B. durch ein höheres Protokoll oder einen Seitenkanal), dass jeweils nur ein Gerät chattet.
So implementieren Sie dies in VHDL:
In Ihrem entity
benötigen Sie einen Stift:
TxRx_pin : inout std_logic;
und in den architecture
beiden Signalen:
signal tx_sig, rx_sig : std_logic;
Verkabeln Sie sie wie folgt:
TxRx_pin <= '0' when tx_sig = '0' else 'Z';
rx_sig <= to_X01(TxRx_pin);
Die erste Zeile kopiert 0
s vom Sender auf den Pin, steuert aber kein 1
s an, sondern verwendet den Z
Zustand, der "getrennt" bedeutet, wodurch der externe Widerstand die Leitung hochziehen kann.
Die zweite Zeile stellt sicher, dass alles, was auf dem Pin erscheint, auf kopiert wird rx_sig
. Der Grund für den to_X01
Anruf ist, dass die Simulationen funktionieren. H
In Ihrer Testbench wird der Pullup-Widerstand modelliert, indem ein (ein sogenannter schwacher Pullup) auf das TxRx-Signal getrieben wird :
TxRx_sig <= 'H';
Ihre FPGA-Logik sucht nicht nach H
s (in der Simulation) und funktioniert daher nicht richtig - die to_X01-Funktion konvertiert H
in 1
(unter anderem nicht relevant für diese Situation).
Übrigens ist es nicht erforderlich, dass ein Mux den Empfang ausschaltet, um ein funktionales Design zu haben, aber Sie möchten ihn vielleicht behalten, damit Sie die von Ihnen übertragenen Daten nicht sehen.
Ignacio Vazquez-Abrams
Chris Stratton
David Tweed
Nik Williams
Nik Williams