FPGA funciona como puente I2C de entrada y salida [cerrado]

Me gustaría usar señales I2C en el FPGA del módulo cypress 2.0 con pines i2c como se muestra a continuación. pero no funciona bien. ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Xilinx FPGA <------------------------------------> módulo MCU (I2c)

.UCF
NET in_scl LOC = "A1";
NET in_sda LOC = "A2";

NET out_scl LOC = "C1";
NET out_sda LOC = "C2";

y en verilog como se muestra a continuación, estoy implementado.

module top();

inout wire in_sda;
inout wire in_scl;

inout wire out_sda;
inout wire out_scl;


assign out_sda = in_sda;
assign out_scl = in_scl;



endmodule

¿Puedes ayudarme qué me estoy perdiendo?

¿Es esta una versión rehecha de una pregunta anterior? ¿Por qué es necesario que el FPGA esté en el sistema, en lugar de solo un cable?
@ pjc50 Hay muchas razones por las que hacer esto. pero no esta vez.
@Neil_UK Todo funciona para alguna definición de trabajo . ¿Cómo se supone que debo adivinar qué está mal con la afirmación "No funciona bien"? ¿Se incendió? ¿No se comunicó en absoluto? ¿El OP no alcanzó la velocidad de transferencia que esperaba alcanzar?
La única forma en que esto es "poco claro" es si la persona que se queja tiene tan poco conocimiento de i2c y lógica programable como el autor de la pregunta. Para cualquier persona con conocimiento real, la naturaleza y la causa de la falla son evidentes de inmediato, razón por la cual esta pregunta recibió dos respuestas.

Respuestas (2)

En la comunicación I2C, se utilizan controladores de colector abierto. El protocolo depende del nivel en la línea que sea el 'cable-OR' de todos los controladores.

Esto significa que, en una interfaz local, un pin puede estar bajo porque un controlador remoto lo está bajando, o lo está bajando por sí mismo.

Obviamente, cualquier búfer que se encuentre entre esta interfaz y las remotas debe poder distinguir por qué la línea está baja. Si es bajo porque un control remoto lo está bajando, entonces también debe bajar para transmitir eso. Si es bajo porque el conductor local lo está bajando, entonces no debe hacerlo, de lo contrario, la línea se atascaría y no sucedería nada más.

Los proveedores de (por ejemplo) optoaisladores diseñados para I2C utilizan varias estrategias. Su salida baja a un nivel diferente al de la interfaz local típica, y los sensores de voltaje pueden distinguir qué controlador lo está bajando. Pero todo es bastante escamoso y depende de que el piloto local tenga un buen rendimiento 'típico'.

Como un bus I2C está diseñado para conectarse al bus, la mejor forma de conectar la FPGA al bus es implementar una entrada y un controlador o/c para cada uno de los dos pines y conectarlos a los dos cables del bus I2C. Esto conserva la conexión directa de todos los elementos que ya están en el autobús. La programación mínima para que el FPGA no interrumpa el tráfico del bus es no controlar las salidas o/c. Para participar en el tráfico de bus se requerirá una pila de protocolos I2C en la FPGA.

Una forma sólida de romper el camino a través de la FPGA es implementar dos pilas I2C en la FPGA, una en cada sentido, para transmitir mensajes. Si bien esto puede parecer una opción bastante pesada, las interfaces I2C están disponibles como IP preescritas para FPGA, y elimina la dificultad de intentar implementar un paso tonto.

I2C utiliza salidas de drenaje abierto/colector. Por esta razón, no puede simplemente usar una salida FPGA típica con una estructura push-pull.

No sé si el FPGA que está utilizando ofrece salidas de drenaje abierto.

De todos modos, debería ser posible imitarlos usando la siguiente estructura (tomada de aquí ): ingrese la descripción de la imagen aquíque se puede inferir usando este código:

always @(ENABLE)
if (ENABLE)
DOUT = 1'bZ;
else
DOUT = 1'b0;

Por supuesto, esta solución solo funciona en una dirección, pero supongo que lo sabe.

Gracias, pero el sensor necesita obtener las señales i2c y poner la señal i2c en el módulo MCU. significa que el módulo MCU lee y escribe en el sensor a través de FPGA. por lo que parece ser necesario bidireccional.
Entonces necesitas reescribir tu código. ¿O esperaba que la entrada produjera una señal de salida?
Podrias ayudarme por favor? He actualizado pero creo que debería haber algo más en mi código. pero no estoy seguro.
Lo siento, no tengo tiempo para eso. Pero puede encontrar una serie de implementaciones en la red ( facultad.lasierra.edu/~ehwang/digitaldesign/public/projects/DE2/… ).