Umgang mit bidirektionaler Kommunikation über 1 Pin

Ich schreibe einen Verilog-Treiber für einen einfachen Temperatursensor, der mit einem FPGA verbunden ist. (Das Datenblatt des Temperatursensors ist hier verfügbar .) Die Kommunikation erfolgt über einen Pin, den sdaPin, an dem der Slave oder Master ein Byte sendet, das dann vom anderen am Ende des Bytes "bestätigt" wird (zwischen den Taktzyklen 9 und 1).

Ich stelle mir vor, dass der beste Weg, dies zu modellieren, darin besteht , sdaeine zu erstellen inout wire, bei der sowohl der Master als auch der Slave sdamit einer assignAnweisung fahren. Mir ist unklar, wie Kollisionen vermieden werden können.

Was passiert, wenn dasselbe inout wiresowohl von der Quelle als auch vom Master angetrieben wird? Was ist der beste Weg, um Sendebestätigungszyklen über einen Pin in Verilog zu modellieren?

Antworten (2)

Wenn sie in I2C an der Reihe sind zu sprechen, treibt entweder der Master oder der Slave die Datenleitung für eine logische 0 auf Low oder wird für eine logische 1 zu einem hochohmigen Eingang.

Wenn es hochohmig wird, lässt es die Leitung im Wesentlichen schweben und ermöglicht dem Pull-up-Widerstand, die Leitung hoch zu ziehen (logische Eins). Wenn es sich um einen hochohmigen Eingang handelt, kann er erkennen, ob die Leitung niedrig angesteuert wird. Wenn er versucht, in diesem Taktzyklus eine logische 1 zu "schreiben", wissen wir, dass eine Art Konflikt aufgetreten ist. Beachten Sie, dass dies der einzige Fall ist, der uns interessiert. Wenn ein Konflikt auftritt, aber am Ende nicht dazu führt, dass sich der resultierende Bitstrom ändert, gehen wir tatsächlich einfach unserer Arbeit nach, ohne einen Fehler zu machen. Wenn ein Konflikt auftritt, ist die Partei, die den Bus zulässt, diejenige, die eine logische 0 erkannt hat, als sie versuchte, eine logische 1 auszugeben.

Ich kenne Verilog nicht, aber in VHDL können wir, wenn wir den STD_LOGIC-Typ verwenden, ihn als „inout“ zuweisen und ihm in einem Prozess den „Z“-Wert (hochohmig) zuweisen und dann den Pin abtasten für ein Hoch oder ein Tief.

Wenn Sie einen I2C-Master schreiben, liegt es in Ihrer Verantwortung, festzustellen, ob die I2C-Leitung verwendet wird, insbesondere nach Start- und Stoppbedingungen zu suchen, um den Beginn und das Ende der Verwendung durch einen anderen möglichen Master zu signalisieren.

HINWEIS: Im Datenblatt steht eine Zweidrahtschnittstelle. Ich bin mir ziemlich sicher, dass dies I2C bedeutet, daher sollte das Obige immer noch relevant sein.

Das Beobachten von Bus-in-Use-Bedingungen ist nur notwendig, wenn ein Master mit anderen Master-Geräten auf dem Bus koexistieren wird. Bei vielen Anwendungen ist das nicht der Fall. Andererseits ist der SCK-Pin bei einigen I2C-Slave-Geräten bidirektional; Geräte, die für ein Bit nicht bereit sind, können SCK niedrig halten, bis sie bereit sind. Um jedes Bit zu takten, wenn solche Geräte verwendet werden, muss der Master SCK freigeben, warten, bis alle Geräte auf dem Bus es ebenfalls freigegeben haben, und es dann erneut aktivieren. Während "Zweidraht" im Allgemeinen "nicht lizenzierte I2C-kompatibel" bedeutet, habe ich übrigens einige "Zweidraht" -Geräte gesehen, die ...
Darüber hinaus müssen Sie auch den Pullup-Widerstand modellieren, in VHDL wäre dies sda <= 'H', und dann das Signal mit auslesen TO_X01(sda). Oder implementieren Sie eine Draht- und Resolverfunktion.
@supercat: Ja, das ist allgemein als "Clock-Stretching" bekannt und führt sogar in einer Single-Master-Umgebung zu Konflikten.
... stark von I2C ausleihen, aber einige seltsame, widerwärtige Dinge tun, von denen ich bezweifle, dass Philips sich dafür entscheiden würde, wie ein Feuchtigkeitssensor, der erfordert, dass SCK während einer Messung niedrig gehalten wird, und asynchron SDA bestätigt, wenn er bereit ist. Ich habe auch einen Zweidraht-Echtzeituhr-Chip gesehen, der Daten LSB-first ein- und ausgibt. Bizarr.

Ihr Temperatursensor verwendet nicht nur 1 Kabel zur Kommunikation, sondern 2. Das Taktkabel ist für die korrekte Kommunikation ebenso wichtig wie das Datenkabel.

Der I2C-Bus ist ziemlich komplex, besonders wenn all sein Schnickschnack implementiert ist. Glücklicherweise implementieren die meisten Chips nicht alle Fähigkeiten, und deshalb ist die Dokumentation auf Datenblattebene oft inkonsistent. Für vollständige und endgültige Informationen können Sie die vollständige Spezifikation von NXP erhalten.

Mir ist unklar, wie Kollisionen vermieden werden können.

Wenn der Temperatursensor das einzige andere Gerät am Bus ist, ist Ihr FPGA immer der Master im Kommunikationsprotokoll. Das heißt, Sie kontrollieren das Taktsignal und wissen immer, ob der Slave gerade den Bus fahren darf.

Normalerweise schreiben Sie eine Zustandsmaschine in Ihr FPGA, die die Daten in und aus dem Slave-Gerät verwaltet und weiß, wann Daten gesendet und wann Daten empfangen werden müssen.

Beachten Sie, dass einige Slave-Geräte zu bestimmten Zeitpunkten in der Transaktion auch die Kontrolle über das Taktsignal geltend machen, wie im Standard beschrieben. Sie tun dies, um die niedrigen Perioden der Uhr zu „dehnen“ und sich selbst Zeit zu geben, eine Messung oder Berechnung abzuschließen, bevor der Master beginnt, die eigentlichen Daten auszutakten. Wenn Ihr Master-Design dies nicht berücksichtigt, kann dies zu einer "Kollision" führen.

Was passiert, wenn derselbe Inout-Draht sowohl von der Quelle als auch vom Master angesteuert wird?

Da I2C-Geräte nur niedrig fahren können, wird im Allgemeinen keiner der Chips beschädigt, wenn es einen Konflikt gibt. Wenn Sie eine logische „1“ senden möchten, treiben Sie die Leitung nicht hoch, sondern versetzen sie in den High-Z-Zustand und lassen einen externen Widerstand hochziehen. Wenn der Slave gleichzeitig eine '0' fährt, wird es keinen Schaden an beiden Geräten geben.

Was ist der beste Weg, um Sendebestätigungszyklen über einen Pin in Verilog zu modellieren?

Ihr Verilog "modelliert" keinen Sendebestätigungszyklus. Es wird die Logik beschreiben, die die korrekten Signale vom Mastergerät erzeugt.

Wenn Sie das Protokoll simulieren möchten, bevor Sie sich auf die Hardware festlegen, schreiben Sie ein zweites Modul mit einer anderen Zustandsmaschine, die auf die Signale des Masters reagiert und die richtigen Signale für das Slave-Gerät erzeugt.