VHDL: ¿cómo usar inout como inout y como normal out?

3

Quería preguntar si es posible usar un pin de inout como inout y normal out? Los dos comportamientos deben ser conmutados a través de un MUX. El motivo de esta implementación de aspecto extraño es que tengo dos placas y quiero usar el mismo flujo de bits. En una placa, el mismo pin está conectado a un LED a través de GPIO y en la otra a mi conexión de bus I2C. El software intenta detectar el I2C y, si tiene éxito, establece un registro. Si no, lo borra.

LED_or_SDA      : inout std_logic; -- port definition

process (register)
begin
    if ( register = '1') then -- software sets this register
       LED_or_SDA <= I2C_SDA; -- here I want to use it as inout
    else
       LED_or_SDA <= gpio_reg; -- here I want to use it as normal out
    end if;
end process;

Esta implementación arroja el error "la red de relleno bidireccional está generando primitivas que no son de búfer" durante la conversión. ¿Hay una solución para esto?

    
pregunta user39236

3 respuestas

1

No hay ninguna razón fundamental por la que un pin inout no pueda usarse como una salida simple ... simplemente ignore la señal de entrada. Sospecho que su problema está en el código VHDL real (en lugar de en la versión que publicó) o en los detalles de cómo está implementando el diseño en un FPGA.

    
respondido por el Joe Hass
1

La mayoría de los FPGA no tienen buffers internos de tres estados, excepto en la IOB (uso los términos de Xilinx). Por lo tanto, se recomienda colocar todas las señales de entrada en el nivel superior (con la lógica de conducción 'Z' asociada), y usar puertos de entrada y salida simples en todo su diseño.

De hecho, dado un puerto de entrada "DataBus", creo las señales "DataBus_in" y "DataBus_out". En todas partes que leo del bus de datos, uso "< = DataBus_in", y cada vez que quiero escribir algo en el bus de datos, uso "DataBus_out <=". Aparte de este fragmento, el puerto de inout DataBus no se utiliza en ningún otro lugar, y las versiones _in y _out se usan exclusivamente.

    DataBus_in <= DataBus;    -- always read the value to xyz_in

tsb_bus_driver: process(OE, DataBus_out) is
begin
    if (OE= '1') then DataBus <= DataBus_out;
    else DataBus <= (others => 'Z');
    end if;
end process tsb_bus_driver;

En otra parte ...

DataBus_out <= foo;  -- example of writing to xyz_out
bar <= DataBus_in;   -- example of reading from xyz_in
    
respondido por el ajs410
1

Es poco probable que pueda sintetizar la conexión de su línea triestada I2C a través de un proceso como ese. Haría esto (supongo que ya tiene señales SDA_IN y SDA_OUT que está utilizando actualmente para crear su SDA) ...

LED_or_SDA <= gpio_reg when register = '0'
           else '0' when register = '1' and I2C_SDA_OUT = '0' 
           else 'Z';
I2C_SDA_IN <= LED_or_SDA when register = '0'
           else '1'; -- idle high
    
respondido por el Martin Thompson

Lea otras preguntas en las etiquetas