Ok, soy un principiante autodidacta que juega con un FPGA y VHDL. He implementado exitosamente una serie de proyectos usando I / O pero solo unidireccional. Los pins están dentro o fuera, pero no inout.
Ahora quiero conectar con un dispositivo externo que tenga un bus de datos bidireccional de 8 bits. Para complicar aún más las cosas, este bus bidireccional se multiplexa con el bus de dirección.
En la parte baja del ciclo de reloj del dispositivo, siempre emitirá los 8 bits superiores de una dirección de 24 bits en el bus de datos. Los 16 bits más bajos no son válidos en ese momento. En la parte alta del ciclo, eliminará los datos o los leerá. Hay una señal activa de activación de escritura baja (RW) para indicar la dirección. Los 16 bits inferiores del bus de datos también son válidos en este momento.
El FPGA está generando el reloj para el dispositivo, así que tengo acceso a la señal del reloj. También me gustaría separar los datos en dos buses de 8 bits para usarlos internamente, uno para leer y otro para escribir.
Por lo tanto, debo configurar los pines para que ingresen y enganchen la parte superior de la dirección durante el período de baja del reloj, y luego durante el período de alta del reloj, debo configurar los pines para que ingresen o salgan y se tripliquen cuando sea apropiado, dependiendo de La señal RW. Así que, básicamente, una versión VHDL del siguiente esquema.
Proporcionaría algunos VHDL que he probado, pero no estoy seguro de cuál de los 20 intentos diferentes de publicación.
Ah, y si alguien tiene algún consejo sobre cómo manejar correctamente las señales de entrada externas simuladas durante la simulación, eso también sería útil. Estoy trabajando con ISim, que es parte de Xilinx ISE.
Actualizar:
Gracias a @Humpawumpa, creo que tengo esto resuelto. Parece que mi problema estaba manejando incorrectamente el estado de alta impedancia del pin de entrada, y además de eso, debido a mi comprensión errónea de cuándo y dónde establecer la impedancia alta, también estaba configurando mi estímulo de simulación, todo mal. p>
Este es el código que se me ocurrió al incorporar la respuesta de Humpawumpa y se ve bien en el simulador. ¡Hurra!
entity addressDemux is
port
(
phi2 : in std_logic;
rw : in std_logic;
data_io : inout std_logic_vector(7 downto 0);
addr_low_in : in std_logic_vector(15 downto 0);
addr_hi_p : out std_logic_vector(7 downto 0);
input_p : out std_logic_vector(7 downto 0);
output_p: in std_logic_vector(7 downto 0);
addr_full_p : out std_logic_vector(23 downto 0)
);
end addressDemux;
architecture struct of addressDemux is
signal addr_hi : std_logic_vector(7 downto 0);
signal input : std_logic_vector(7 downto 0) := (others => '0');
signal output : std_logic_vector(7 downto 0);
signal addr_low : std_logic_vector(15 downto 0) := (others => '0');
begin
addr_hi <= data_io when phi2 = '0';
data_io <= output when phi2 = '1' and rw = '0' else (others => 'Z');
input <= data_io when phi2 = '1' and rw = '1';
addr_low <= addr_low_in when phi2 = '1';
addr_hi_p <= addr_hi;
addr_full_p(23 downto 16) <= addr_hi;
addr_full_p(15 downto 0) <= addr_low;
input_p <= input;
output <= output_p;
end struct;
Básicamente, lo que me estaba fallando era configurar el inout pin data_io a alta impedancia. Al provenir de una configuración de fondo de desarrollo de software data_io a 'Z' en el período de alta del reloj y luego leer los datos me confundió. En la configuración del software, una variable con algún valor no le da un valor diferente cuando lo lee. Así que pensé que si lo configuraba en "Z", mi entrada sería "Z" cuando lo leí. Todo es código correcto, jaja. Hay mucho que desaprender, supongo.