Multiplexación de un bus I2C entre dos maestros en un FPGA de Xilinx

Tengo un solo bus I2C externo (pines SDA y SCL). Actualmente, esto está controlado por un núcleo de IP de terceros que proporcionó puertos de entrada y salida "implícitos" en el MPD, específicamente:

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

Encontré una situación en la que quiero poder hablar con un dispositivo en ese bus independientemente del núcleo de IP (en un momento en que el núcleo de IP en sí se puede restablecer para saber que no puede interferir). Intenté crear un axi_iicmaestro separado y conectarlo a los mismos puertos externos, pero esto no funciona porque se enfada con los múltiples controladores de salida conectados entre sí.

Entonces, creo que necesito un multiplexor I2C simple como lógica de unión entre los dos maestros, y creo que sé cómo hacerlo en términos de las señales internas _Ide cada maestro _O, _Tpero no estoy seguro de cómo "extraer" esos señales internas para el núcleo existente dado el MPD anterior ( están presentes en el VHDL subyacente).

Por el momento, acabo de modificar manualmente el archivo MPD para exponer estas señales, pero me preguntaba si hay una mejor manera de hacerlo (obteniendo las señales sin cambiar el archivo MPD, o haciendo todo el asunto multimaestro I2C). ); Si bien la edición manual es factible, los cambios en el archivo MPD pueden perderse cuando se actualiza el núcleo, por lo que es propenso a errores.

Otra solución que he considerado (pero no estoy seguro si me gusta, aunque todavía es posible ya que el pinout de FPGA aún no es definitivo) es enrutar dos veces el bus externo (para que el SDA externo vaya a dos FPGA separados). pines, uno para el núcleo de terceros y otro para el nuevo núcleo). Sin embargo, esto parece bastante feo y derrochador, pero no soy un experto. :)

Entonces, para que quede claro. La instancia del bloque I2C que está utilizando tiene una ubicación dedicada con ubicaciones de pines y no puede agregar un mux entre el bloque y los pines para insertar su propio bus maestro I2C o no sabe cómo escribir el código para captar esas señales internas.? ¿Cómo se llama el core que estás usando?
No. El MPD principal simplemente expone solo las señales implícitas de tres estados, no las señales internas _I _O _T y, como resultado, si trato de poner un mux a esas señales, se queja de que no están en el MPD. Si los agrego manualmente al MPD, el compilador vuelve a estar contento, pero esto tampoco es ideal ya que el archivo MPD (rara vez) se reemplaza cuando el proveedor principal publica una actualización. (El núcleo no es un núcleo I2C, principalmente hace otras cosas; tiene algunas funciones que usan I2C pero están completamente fuera de mi control). Quiero insertar un mux para poder hacer algo de mi propio control.
Tengo entendido que, dado que I2C es bidireccional, no es factible multiplexar las señales tristate dentro de la FPGA, solo las señales internas _I _O _T. Lo que me molesta es que con el archivo MPD predeterminado sin editar, el compilador obviamente sabe que las señales internas existen y las asigna correctamente al VHDL (que define solo las señales internas), pero no me permite especificarlas directamente en el archivo MHS a menos que estén explícitamente enumerados por separado en el MPD.
PERO estás diciendo que conoces el estado del otro controlador, por lo que sabes que no puede interferir, así que sí, es completamente factible. Si las herramientas te permiten hacerlo internamente es otra cuestión.
I2C es un 'colector' abierto, por lo que si puede prescindir de 2 pines, puede crear sus propios pines I2C y simplemente conectarlos a los pines I2C del núcleo externamente.
@WoutervanOoijen: Sí, mencioné esa idea en el párrafo final. Parece un poco feo, aunque también lo es editar el archivo MPD manualmente.

Respuestas (2)

Solo en aras de la exhaustividad (ya que recientemente me recordaron esta pregunta), repetiré la respuesta que finalmente decidí:

Dado el siguiente fragmento de MPD proporcionado por el proveedor principal:

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

Lo sustituyo por lo siguiente:

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

Esto funciona bien (ya que las señales subyacentes se definieron en el VHDL de todos modos). Es un poco complicado ya que tengo que recordar hacer esto cada vez que obtengo un núcleo actualizado del proveedor, pero esto es lo suficientemente infrecuente como para no ser un gran problema. (He estado tratando de persuadir al proveedor para que lo agregue, pero hasta ahora no he tenido mucha suerte).

Si no puede resolver el problema internamente en el FPGA, use puertas de transmisión externamente para enviar dos maestros a un bus externo.

No, definitivamente no hay necesidad de puertas externas. Esto es puramente un problema del compilador FPGA.