Lo que se infiere depende de si la señal es o no una señal externa (una que va hacia / desde un puerto de E / S) o una interna.
Toma la siguiente construcción:
module test (
inout bidirPin,
input toPin,
input direction,
output fromPin
);
assign bidirPin = direction ? 1'bz : toPin;
assign fromPin = bidirPin;
Esto dice, cuando la señal direction
es baja, entonces bidirPin
es una salida y la señal toPin
está conectada al pin. Cuando direction
está en alto, entonces bidirPin
se convierte en una entrada. En todos los casos, la señal fromPin
representa los datos actuales del pin.
Este constructo requiere que el FPGA tenga buffers de E / S bidireccionales (triplete). Muchos (¿la mayoría?) Lo hacen, pero no todos los pines en todos los dispositivos lo admiten.
Si la misma construcción se utilizara en su lugar internamente (por ejemplo, tiene varias instancias del módulo anterior y conecta todos los pines de entrada a un solo cable), entonces, claramente, lo que se infiere debe ser diferente si fuera un I / O pin. La mayoría, si no todos los FPGA, no tienen redes internas de enrutamiento de estado. En otras palabras, High-Z no es posible.
Sin embargo, la lógica es sintetizable. Lo que sucede es que el sintetizador mira todas las señales inout
que se conectan a la misma red, y simplemente deduce la lógica del multiplexor. Esto representa efectivamente lo mismo, pero requiere una lógica de arbitraje adicional. En general, cualquier posible conflicto de bus se resuelve utilizando codificadores de prioridad en el multiplexor, de modo que solo uno de los puertos pueda entregar su señal a la vez.
Esta puede ser una forma muy útil de conectar muchos periféricos (por ejemplo, SPI, UART, RAM, etc.) a un bus de datos compartido si está diseñando algo con una arquitectura similar a la de un microcontrolador. Usar el alto Z permite que el sintetizador se encargue de cualquier lógica de arbitraje. Esto puede hacer que la depuración sea más difícil ya que tiene que seguir la lógica adicional agregada en cualquier visor de listas de red RTL, pero es una forma perfectamente válida de hacer las cosas.
En la simulación, High-Z puede ser un estado aceptable (p. ej., si está observando un pin de E / S triplicado) o un indicador de un problema importante (p. ej., si utiliza un bucle de generación y pierde un bit en un bus de datos irá alto-Z).
High-Z puede ayudarlo a identificar problemas causados por señales no conectadas provenientes de cosas como generar bucles, o si lo hubiera dicho, escribir incorrectamente un nombre de variable que resulte en dos cosas que no estén conectadas correctamente. Si está esperando que una señal en la simulación pueda ir a High-Z, entonces no hay problema. Si no lo está esperando, entonces se justifica una mayor investigación de la causa.
Los buses internos de alta Z (aquellos donde se infiere el arbitraje) pueden presentar un dolor de cabeza por simulación adicional. Si simula una lista de redes de síntesis posterior, por ejemplo, es posible que nunca vea High-Z en el bus, ya que la lógica de arbitraje ya se ha deducido. Si simula desde un nivel de origen, es probable que vea que aparece High-Z en el bus, ya que el simulador está feliz de permitir High-Z, ya que no sabe qué van a deducir las herramientas de síntesis, por lo que el simulador se queda exactamente a lo que has escrito en el código.