Autor Tema: Buses bidireccionales con VHDL  (Leído 12286 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado capapaz

  • PIC10
  • *
  • Mensajes: 1
Buses bidireccionales con VHDL
« en: 20 de Septiembre de 2005, 11:48:00 »
 Si alguien me puede mandar algun ejemplillo que sepa que funcione y que contenga lineas bidireccionales lo agradecería mucho. Me urge bastante

Un saludo a todos.




Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Buses bidireccionales con VHDL
« Respuesta #1 en: 21 de Septiembre de 2005, 04:19:00 »
Buenas.

Los buses bidireccionales se deben realizar transformando un bus de salida en triestado. La salida del triestado se coloca en alta impedancia mediante una señal de control y se puede leer entonces el dato de entrada.
Por lo tanto, si quieres leer/escribir datos de una memoria, o construir un módulo I2C, etc, tu diseño deberá tener dos buses, uno de lectura y otro de escritura y unirlos mediante el ejemplo que te pongo a continuacion:

Codigo:
--------------------------------------------------------------------------------
-- Modulo para conectar un bus bidireccional.
-- El bus bus bidireccional es el puerto "data_bus".
-- Los datos que se quieren escribir en el bus vienen en el puerto "data_in".
-- Los datos que se leen del bus salen por el puerto "data_out".
-- Para controlar la dirección de los datos se utiliza la señal "control".
-- Si control vale 0 el bus se configura como salida, y si vale 1 como entrada.
--------------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use ieee.numeric_std.all;

entity bus_bidir is
  generic (
    C_DATA_WIDTH : integer := 8 --Ancho de bus parametrizable, por defecto a 8 bits.
    );
  port (
    data_bus     : inout std_logic_vector(C_DATA_WIDTH-1 downto 0);
    data_in      : in    std_logic_vector(C_DATA_WIDTH-1 downto 0);
    data_out     : out   std_logic_vector(C_DATA_WIDTH-1 downto 0);
    control      : in    std_logic
    );
end entity bus_bidir;

architecture behavioral of bus_bidir is

begin    -- architecture behavioral

  with control select
    data_bus <= data_in when "0",            --  Conecta con la salida cuando control vale 0
                (others => "Z") when others; --  Lo deja abierto cuando control vale 1

  data_out <= data_bus;  -- Bus de lectura
end architecture behavioral;


Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Buses bidireccionales con VHDL
« Respuesta #2 en: 12 de Noviembre de 2005, 16:45:00 »
Como sería entonces si queremos una pullup a la salida del buffer triestado?
Haciendo mas asignaciones en el ámbito concurrente?
La función de resolución se encargaria del resto no?

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Buses bidireccionales con VHDL
« Respuesta #3 en: 18 de Noviembre de 2005, 05:15:00 »
Para colocar una resistencia de PULLUP en alguna E/S de una FPGA se utiliza el fichero con extensión UCF, donde se asignan las Entradas y Salidas de nuestro diseño a los pines de la FPGA. Aqui te pongop un ejemplo:

Codigo:
Net Entradas<3>  LOC=c16;
Net Entradas<3>  PULLUP;
Net Entradas<2>  LOC=d16;
Net Entradas<2>  PULLUP;
Net Entradas<1>  LOC=e16;
Net Entradas<1>  PULLUP;
Net Entradas<0>  LOC=g15;
Net Entradas<0>  PULLUP;


En este ejemplo tengo un bus de entrada de 4 bits que tiene resistencias de pullup. Si se quieren colocar resistencias de pulldown, simplemente hay que utilizar el comando PULDOWN; Sencillo noSonrisa Gigante

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Buses bidireccionales con VHDL
« Respuesta #4 en: 19 de Noviembre de 2005, 05:02:00 »
Gracias por tu respuesta Antonio.
Al final lo hice así:



Codigo:

library ieee;
use ieee.std_logic_1164.all;

entity PAD is
port(PUERTO: inout STD_LOGIC;
     DINOUT: in STD_LOGIC;
     DOUTIN: out STD_LOGIC;
     CONTROL: in STD_LOGIC);
end PAD;

architecture F of PAD is
  signal pullup: STD_LOGIC;
begin
  pullup <= "H";
  PUERTO <= pullup;
  with CONTROL select
      PUERTO <= "Z" when "0",  -- Buffer cerrado
                DINOUT when others;
  DOUTIN <= PUERTO;
end F;



Para hacerlo de la forma que planteas como sería entonces?

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Buses bidireccionales con VHDL
« Respuesta #5 en: 22 de Noviembre de 2005, 06:55:00 »
En el código que muestras hay una asignación a la señal PUERTO que puede crear conflictos. Le asignas las señales "pullup" y "DINOUT" simultaneamente.

Te compila el sintetizador ese código?

La forma que yo plateo es sintetizar el archivo que he puesto más arriva. Una vez sintetizado, el programa que se encarga de mapear el diseño en nuestra FPGA conecta las entradas y salidas del diseño a los pines que nosostros le asignemos.

Esta asignación de pines se puede realizar gráficamente en el programa o editando un archivo con extensión ".udf", que después añadiremos al proyecto. Es en este archivo donde, además de asignar los pines externos, podemos asignar a las entradas del diseño las resistencias de PULLUP o PULLDOWN


Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Buses bidireccionales con VHDL
« Respuesta #6 en: 22 de Noviembre de 2005, 09:14:00 »
No tiene por qué haber conflictos a pesar de que haya más de un driver para una misma señal.Por eso me refería antes a la función de resolución.
El tipo std_logic admite 9 posibles valores diferentes : "1", "0", "H", "L", "Z", etc...
...además de ser un tipo resuelto(tiene asociada una función de resolución).
Cuando hay más de una asignación para una misma señal,el compilador llama a la función de resolución,la cual va tomando los valores asignados dos a dos y devuelve cada vez un valor resultante de "sumar" esos dos valores.
Así,si a una señal le asignamos,dentro del ámbito concurrente,el valor "1"(1 fuerte)
y también el valor "L"(cero débil,debido a una pulldown por ejemplo),el resultado será un "1".
El resultado que se obtiene de cada pareja de asignaciones lo determina la tabla de resolución:

Codigo:


constant RESOLUTION_TABLE : STDLOGIC_TABLE := (
-- ---------------------------------------------------------
-- | U    X    0    1    Z    W    L    H    -        |   |
-- ---------------------------------------------------------
(   "U", "U", "U", "U", "U", "U", "U", "U", "U" ), -- | U |
(   "U", "X", "X", "X", "X", "X", "X", "X", "X" ), -- | X |
(   "U", "X", "0", "X", "0", "0", "0", "0", "X" ), -- | 0 |
(   "U", "X", "X", "1", "1", "1", "1", "1", "X" ), -- | 1 |
(   "U", "X", "0", "1", "Z", "W", "L", "H", "X" ), -- | Z |
(   "U", "X", "0", "1", "W", "W", "W", "W", "X" ), -- | W |
(   "U", "X", "0", "1", "L", "W", "L", "W", "X" ), -- | L |
(   "U", "X", "0", "1", "H", "W", "W", "H", "X" ), -- | H |
(   "U", "X", "X", "X", "X", "X", "X", "X", "X" )  -- | - |
);




Yo de momento estoy trabajando únicamente con simulaciones.Dentro de unos días comenzaré a trabajar de forma práctica con las fpga y podré comprobar si esto realmente funciona o no,pero por ahora sólo me puedo limitar a creerme lo que el simulador me cuenta.
Un saludote

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Buses bidireccionales con VHDL
« Respuesta #7 en: 25 de Noviembre de 2005, 06:37:00 »
OK ya entiendo eso de las funciones de resolucion.
Sin embargo creo que cuando lo pruebes, siempre leerás un uno en el bus de entrada, ya que esta función de resolución creará una lógica interna que cuando la señal de control ponga al buffer triestado en alta impedancia, entregue un "1" lógico a la señal puerto.
Esto funcionará en simulación pero a la hora de probarlo físicamente, la señal puerto estará a uno y no admitirá un cero a la entrada.
Cuando lo pruebes físicamente, utiliza una resistencia de 1K a la entrada no vaya a ser que la lógica interna fuerze un uno y tu le metas un cero y pete algo.

A lo mejor me equivoco y el sintetizador es lo suficientemente "inteligente" como para configurar automáticamente la resistenciasde pullup del pin que asignes a esta señal y eliminar la lógica interna. Ya me contarás.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Buses bidireccionales con VHDL
« Respuesta #8 en: 25 de Noviembre de 2005, 07:43:00 »
Ya te digo.
Esto es vhdl simple y llano.Unicamente compilado y simulado.Ni siquiera he pasado por la etapa de síntesis lógica,tarea que me toca probar en estos días.
A ver que tal se da.

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Buses bidireccionales con VHDL
« Respuesta #9 en: 21 de Diciembre de 2005, 12:48:00 »
Retomo este tema para decir que he probado el código de modulay y no sintetiza. Para la simulación funciona sin problemas pero para la síntesis da un error de "multisource". Aqui dejo el log de salida del sintetizador:

=========================================================================
*                          HDL Compilation                              *
=========================================================================
Compiling vhdl file "c:/prueba/bidir.vhd" in Library work.
Entity <PAD> compiled.
Entity <PAD> (Architecture <F>Giño compiled.

=========================================================================
*                            HDL Analysis                               *
=========================================================================
Analyzing Entity <pad> (Architecture <F>Giño.
Entity <pad> analyzed. Unit <pad> generated.


=========================================================================
*                           HDL Synthesis                               *
=========================================================================

Synthesizing Unit <pad>.
    Related source file is "c:/prueba/bidir.vhd".
    Found 1-bit tristate buffer for signal <PUERTO>.
    Summary:
   inferred   1 Tristate(s).
Unit <pad> synthesized.


=========================================================================
*                       Advanced HDL Synthesis                          *
=========================================================================

Advanced RAM inference ...
Advanced multiplier inference ...
Advanced Registered AddSub inference ...
Dynamic shift register inference ...

=========================================================================
HDL Synthesis Report

Macro Statistics
# Tristates                        : 1
 1-bit tristate buffer             : 1

=========================================================================

=========================================================================
*                         Low Level Synthesis                           *
=========================================================================

ERROR:Xst:528 - Multi-source in Unit <pad> on signal <PUERTO>
Sources are:
   Output signal of BUFT instance <PUERTO_DINOUT_0>
   Signal <PUERTO> in Unit <pad> is assigned to VCC
CPU : 4.42 / 5.63 s | Elapsed : 4.00 / 5.00 s
 
-->

Total memory usage is 79704 kilobytes

Number of errors   :    0 (   0 filtered)
Number of warnings :    1 (   0 filtered)
Number of infos    :    0 (   0 filtered)

ERROR: XST failed
Process "Synthesize" did not complete.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Buses bidireccionales con VHDL
« Respuesta #10 en: 22 de Diciembre de 2005, 16:16:00 »
Haciendo un pequeño cambio se resuelve el problema de la síntesis:

Codigo:


library ieee;
use ieee.std_logic_1164.all;

entity PAD is
port(PUERTO: inout STD_LOGIC;
     DINOUT: in STD_LOGIC;
     DOUTIN: out STD_LOGIC;
     CONTROL: in STD_LOGIC);
end PAD;

architecture F of PAD is
  signal PUERTOi: STD_LOGIC;
begin
  PUERTOi <= "H"; -- Efecto pullup
  with CONTROL select
      PUERTOi <= "Z" when "0",  -- Buffer cerrado
                DINOUT when others;
  PUERTO <= PUERTOi;
  DOUTIN <= PUERTO;
end F;




No lo he simulado pero imagino que irá bien.
Hasta después de vacaciones no tendré oportunidad de probarlo sobre la fpga.
He estado intentando visualizar la lógica generada,cosa fácil en el ISE foundation 4.1,pero
ahora estoy usando el ISE webpack 7.1 y no doy con la tecla
Un saludo

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Buses bidireccionales con VHDL
« Respuesta #11 en: 22 de Diciembre de 2005, 18:52:00 »
Sintetiza bien pero el esquema RTL que me saca es raro raro raro loco


Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Buses bidireccionales con VHDL
« Respuesta #12 en: 23 de Diciembre de 2005, 00:28:00 »
Codigo:


library ieee;
use ieee.std_logic_1164.all;

entity PAD is
port(PUERTO: inout STD_LOGIC;
     DINOUT: in STD_LOGIC;
     DOUTIN: out STD_LOGIC;
     CONTROL: in STD_LOGIC);
end PAD;

architecture F of PAD is  
 
component pullup
  port(o: OUT STD_LOGIC);
end component;
 
begin
  u0: pullup port map(o => PUERTO);  
  with CONTROL select
    PUERTO <= "Z" when "1",  -- Buffer cerrado
               DINOUT when others;
  DOUTIN <= PUERTO;
end F;




Chirría un poco al sintetizar y al simular es como si la pullup no estuviera,por considerar "desconocido" el componente pullup,pero la lógica que genera parece correcta



La cuestión es que he estado intentando modelar yo mismo el componente,pero haciéndolo sólo consigo obtener el mismo error multi-source.
He conseguido simularlo usando el modelo x_pu que viene en la librería simprim del modelsim y va a la perfección,pero no sé como hacer para añadir esta librería al ISE para poder sintetizar.
He tomado como referencia estos enlaces

http://www.xilinx.com/xlnx/xil_ans_display.jsp?BV_UseBVCookie=yes&getPagePath=2145&iLanguageID=1
http://www.hdlworks.com/products/ease/i2c_vhdl/archa0a0a0409106bfc3915356000fa08f32.htm



Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Buses bidireccionales con VHDL
« Respuesta #13 en: 23 de Diciembre de 2005, 06:15:00 »
Ya genera el esquema correctamente:



Te genera una "caja negra" para el módulo pullup.

Voy a probarlo en la FPGA a ver que tal.

Desconectado antoniof

  • Moderadores
  • PIC24F
  • *****
  • Mensajes: 729
RE: Buses bidireccionales con VHDL
« Respuesta #14 en: 23 de Diciembre de 2005, 06:39:00 »
Funciona a la perfección Modulay. RebotadoRebotadoRebotadoRebotado

La resistencia de pullup es de aproximadamente 2K en mi Sparan3 XC3S200.

He puesto un led a la señal puerto y enciende más cuando está el bus como salida (control = 0) que cuando está como entrada, con lo cual no hay cortocircuito posible entre la pullup y masa.