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 sda
Pin, 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 , sda
eine zu erstellen inout wire
, bei der sowohl der Master als auch der Slave sda
mit einer assign
Anweisung fahren. Mir ist unklar, wie Kollisionen vermieden werden können.
Was passiert, wenn dasselbe inout wire
sowohl von der Quelle als auch vom Master angetrieben wird? Was ist der beste Weg, um Sendebestätigungszyklen über einen Pin in Verilog zu modellieren?
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.
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.
Superkatze
Ben Voigt
sda <= 'H'
, und dann das Signal mit auslesenTO_X01(sda)
. Oder implementieren Sie eine Draht- und Resolverfunktion.Ben Voigt
Superkatze