Interfaz correcta a una señal bidireccional

Fondo

Estoy diseñando una interfaz en VHDL que se conecta a una señal bidireccional. Sin embargo mi experiencia en la dinámica del Diseño de Hardware es limitada. Lo que tengo en este momento es el siguiente:ingrese la descripción de la imagen aquí

Dentro de la caja roja está lo que hay en el FPGA, fuera de eso están los componentes eléctricos.

El módulo RX busca una señal BAJA para un bit de inicio. Para evitar interferencias entre el módulo TX y el módulo RX: coloqué un Mux controlado por el módulo TX para pasar ALTO siempre que esté transmitiendo.

El circuito externo asegura que mi TX nunca maneje la línea ALTA para evitar cortocircuitos.

El problema

Cuando los módulos RX y TX están separados, funcionan perfectamente. El RX recibe y lee la señal correctamente y el TX transmite (no en la línea bidireccional; en cambio: mi osciloscopio) perfectamente. Sin embargo, cerrar el interruptor para combinar los dos es una catástrofe. El módulo RX parece dejar de responder.

La pregunta

No estoy seguro de si se trata de un problema general de diseño o algo pequeño y estúpido con mi VHDL.

Entonces, ¿es este un método aceptable para interactuar con una señal bidireccional? Tengo la sensación de que hay algo muy mal en mi configuración. Solo busco sugerencias, críticas o ideas generales.

Si esta es una configuración correcta, entonces al menos puedo confiar en investigar el VHDL para el problema yo mismo y saber que mis esfuerzos no serán en vano debido a un diseño general inherentemente defectuoso.

Buscando en Google: "Interfaz con un bus bidireccional" parece sugerir búferes Tri-State. ¿Es este un mejor enfoque?

Extra

Me siento molesto por molestarlos constantemente debido a la falta de comprensión conceptual, por lo que si pudiera obtener una sugerencia sobre libros o varias fuentes de investigación para diseñar hardware conceptualmente, sería fantástico.

Las hojas de datos de MCU generalmente tienen un esquema equivalente de sus pines de E/S. Encuentro, en general, que (las hojas de datos de MCU) son un gran recurso para descubrir cómo se juntan varios bits de interfaz.
Los búferes de tres estados serían una solución normal, al menos para aplicaciones de rendimiento medio. Pero si quiere ir con su mux externo, use el osciloscopio para examinar qué hay en el pin RX cuando está conectado, pero en modo de recepción con algo más transmitiendo: ¿la señal llega al pin RX o no?
¿Qué familia de FPGA estás usando? Las herramientas de depuración interna (p. ej., Xilinx ChipScope, Altera SignalTap) pueden ser herramientas muy valiosas en este tipo de situaciones. Si esa no es una opción, ¿tiene pines de repuesto a los que pueda sacar señales internas clave?
@ChrisStratton Podría dividir esa señal en un pin y medirla con el alcance. Esto probaría efectivamente si mi método mux es funcional o no.
@DaveTweed El FPGA es un Spartan 3A, tendré que investigar estas herramientas que mencionas. ¡También tengo muchos pines de repuesto! He estado rompiendo algunas señales, pero no he profundizado demasiado. ¡Gracias!

Respuestas (1)

Tristate es lo que quieres. O, como tiene una resistencia pull-up externa, una unidad de drenaje abierto . También verá que el colector abierto significa lo mismo: depende del estilo de los transistores utilizados, pero la idea fundamental es la misma. ISO9141 (diagnóstico automotriz) funciona de esta manera, por ejemplo.

El drenaje abierto solo significa que el pin del controlador solo puede bajar la señal externa, pero no puede subirla; la resistencia permitirá que la línea "flote" suavemente hacia arriba. También significa que varios dispositivos pueden controlar la línea de comunicación, por lo que debe asegurarse (por ejemplo, a través de un protocolo de nivel superior o un canal lateral) de que solo un dispositivo chatea a la vez.

Para implementar esto en VHDL:

En tu entitynecesitas un pin:

TxRx_pin : inout std_logic;

y en las architecturedos señales:

signal tx_sig, rx_sig : std_logic;

Conéctalos así:

TxRx_pin <= '0' when tx_sig = '0' else 'Z';
rx_sig <= to_X01(TxRx_pin);

La primera línea copia 0s del transmisor en el pin, pero no maneja 1s, sino que usa el Zestado que significa "desconectado", lo que permite que la resistencia externa levante la línea.

La segunda línea asegura que todo lo que aparece en el marcador se copie en rx_sig. El motivo de la to_X01llamada es hacer que las simulaciones funcionen. En su banco de pruebas, la resistencia pullup se modela al conducir un H(un llamado pullup débil) a la señal TxRx:

TxRx_sig <= 'H';

Su lógica FPGA no buscará Hs (en simulación), por lo que no funcionará correctamente: la función to_X01 se convierte Hen 1(entre otras cosas que no son relevantes para esta situación).

Por cierto, no es necesario que un mux apague la recepción para tener un diseño funcional, pero es posible que desee mantenerlo para que no vea los datos que está transmitiendo.