Multiplexen eines I2C-Busses zwischen zwei Mastern auf einem Xilinx-FPGA

Ich habe einen einzigen externen I2C-Bus (SDA- und SCL-Pins). Dies wird derzeit von einem IP-Core eines Drittanbieters gesteuert, der "implizite" Inout-Ports in der MPD bereitstellt, insbesondere:

PORT IIC_DATA = "", DIR = IO, THREE_STATE=TRUE
PORT IIC_CLOCK = "", DIR = O, THREE_STATE=TRUE

Ich bin in eine Situation geraten, in der ich unabhängig vom IP-Core mit einem Gerät auf diesem Bus sprechen möchte (zu einem Zeitpunkt, an dem der IP-Core selbst zurückgesetzt werden kann, damit ich weiß, dass er nicht stören kann). Ich habe versucht, einen separaten axi_iicMaster zu erstellen und ihn an dieselben externen Ports anzuschließen, aber das funktioniert nicht, da es sich über mehrere miteinander verbundene Ausgangstreiber aufregt.

Ich denke also, ich brauche einen einfachen I2C-Multiplexer als Glue-Logik zwischen den beiden Mastern, und ich glaube, ich weiß, wie das in Bezug auf die internen _I, _O, _TSignale jedes Masters geht, aber ich bin mir nicht sicher, wie ich diese "extrahieren" soll interne Signale für den vorhandenen Kern, wenn die MPD oben gegeben ist (sie sind in der zugrunde liegenden VHDL vorhanden).

Im Moment habe ich die MPD-Datei nur manuell modifiziert, um diese Signale freizulegen, aber ich habe mich gefragt, ob es einen besseren Weg gibt, dies zu tun (entweder an die Signale heranzukommen, ohne die MPD-Datei zu ändern, oder das ganze I2C-Multi-Master-Ding zu machen ); Während die manuelle Bearbeitung funktioniert, können die Änderungen an der MPD-Datei verloren gehen, wenn der Kern aktualisiert wird, sodass sie fehleranfällig ist.

Eine andere Lösung, die ich in Betracht gezogen habe (aber ich bin mir nicht sicher, ob sie mir gefällt, obwohl es immer noch möglich ist, da die FPGA-Pinbelegung noch nicht endgültig ist), besteht darin, den externen Bus doppelt zu routen (so dass der externe SDA zu zwei separaten FPGAs geht). Stifte, einen für den Drittanbieterkern und einen für den neuen Kern). Das scheint zwar ziemlich hässlich und verschwenderisch, aber dann bin ich kein Experte. :)

Also, nur um klar zu sein. Die Instanz des I2C-Blocks, die Sie verwenden, hat eine dedizierte Platzierung mit Pin-Positionen, und Sie können keinen Mux zwischen dem Block und den Pins hinzufügen, um Ihren eigenen I2C-Busmaster einzufügen, oder Sie wissen nicht, wie Sie den schreiben sollen Code, um diese internen Signale zu erfassen.? Wie heißt der Kern, den du verwendest?
Nein. Die Kern-MPD legt einfach nur die impliziten Tristate-Signale offen, nicht die internen _I _O _T-Signale, und wenn ich versuche, einen Mux in diese Signale einzufügen, beschwert sie sich, dass sie nicht in der MPD sind. Wenn ich sie manuell zum MPD hinzufüge, ist der Compiler wieder glücklich, aber das ist auch nicht ideal, da die MPD-Datei (selten) ersetzt wird, wenn der Kernhersteller ein Update veröffentlicht. (Der Kern ist kein I2C-Kern, er macht hauptsächlich andere Dinge; er hat einige Funktionen, die I2C verwenden, aber sie sind völlig außerhalb meiner Kontrolle.) Ich möchte einen Mux einfügen, damit ich einen Teil meiner eigenen Kontrolle übernehmen kann.
Mein Verständnis ist, dass es nicht möglich ist, die Tristate-Signale selbst innerhalb des FPGA zu muxen, da I2C bidirektional ist, sondern nur die internen _I _O _T-Signale. Was mich stört, ist, dass der Compiler bei der standardmäßigen unbearbeiteten MPD-Datei offensichtlich weiß , dass die internen Signale vorhanden sind, und sie ordnungsgemäß der VHDL zuordnet (die nur die internen Signale definiert), aber ich kann sie nicht direkt in angeben MHS-Datei, es sei denn, sie sind in der MPD explizit separat aufgeführt.
Aber Sie sagen, dass Sie den Zustand des anderen Controllers kennen, damit Sie wissen, dass er nicht stören kann, also ja, es ist durchaus machbar. Ob die Tools es Ihnen erlauben, dies intern zu tun, ist eine andere Frage.
I2C ist ein offener "Kollektor". Wenn Sie also 2 Pins übrig haben, können Sie Ihre eigenen I2C-Pins erstellen und diese einfach extern mit den I2C-Pins des Kerns verbinden.
@WoutervanOoijen: Ja, ich habe diese Idee im letzten Absatz erwähnt. Es scheint ein bisschen hässlich zu sein, obwohl das manuelle Bearbeiten der MPD-Datei auch so ist.

Antworten (2)

Nur der Vollständigkeit halber (da ich kürzlich an diese Frage erinnert wurde) werde ich die Antwort wiederholen, für die ich mich schließlich entschieden habe:

Angesichts des folgenden MPD-Snippets, das vom Core-Anbieter bereitgestellt wird:

PORT IIC_DATA = "", DIR = IO, THREE_STATE=TRUE
PORT IIC_CLOCK = "", DIR = O, THREE_STATE=TRUE

Ich ersetze es durch Folgendes:

PORT IIC_DATA_I = "", DIR = I
PORT IIC_DATA_O = "", DIR = O
PORT IIC_DATA_T = "", DIR = O
PORT IIC_DATA = "", DIR = IO, THREE_STATE=TRUE, TRI_I = IIC_DATA_I, TRI_O = IIC_DATA_O, TRI_T = IIC_DATA_T
PORT IIC_CLOCK_O = "", DIR = O
PORT IIC_CLOCK_T = "", DIR = O
PORT IIC_CLOCK = "", DIR = O, THREE_STATE=TRUE, TRI_O = IIC_CLOCK_O, TRI_T = IIC_CLOCK_T

Dies funktioniert gut (da die zugrunde liegenden Signale sowieso in der VHDL definiert wurden). Es ist ein bisschen mühsam, da ich daran denken muss, dies jedes Mal zu tun, wenn ich einen aktualisierten Kern vom Anbieter erhalte, aber das ist selten genug, um keine große Sache zu sein. (Ich habe versucht, den Verkäufer davon zu überzeugen, es selbst hinzuzufügen, hatte aber bisher nicht viel Glück.)

Wenn Sie das Problem nicht intern im FPGA lösen können, verwenden Sie externe Übertragungsgatter, um zwei Master auf einen externen Bus zu leiten.

Nein, externe Tore sind definitiv nicht erforderlich. Dies ist ein reines FPGA-Compiler-Problem.