Banco de pruebas para puerto INOUT en VHDL

Estaba buscando en Internet y stackexchange la solución, pero aún no sé por qué no funciona. Las soluciones que encontré aquí funcionarán, pero probablemente todavía estoy haciendo algo mal.

Estoy escribiendo 'código' VHDL. Tengo en mi diseño puertos INOUT. En libero soc, la síntesis y la compilación funcionan bien. Ahora me gustaría simular mi diseño y aquí está el problema. Estoy usando Mentor Graphics ModelSim. Durante el banco de pruebas de compilación tengo un error

Los 'datos' de la señal no resuelta tienen múltiples fuentes.

architecture architecture_max11046_interface_tb of max11046_interface_tb is

component max11046_interface is
    port (
        -- Clock and resets
        i_clk           : in std_ulogic;
        i_rst_asyn      : in std_ulogic;
        i_rst_syn       : in std_ulogic;

        -- Max11046 interface
        o_cs        : out std_ulogic;
        o_wr        : out std_ulogic;
        o_rd        : out std_ulogic;
        o_convst    : out std_ulogic;
        o_shdn      : out std_ulogic;
        i_eoc       : in  std_ulogic;
        io_data      : inout  std_ulogic_vector(15 downto 0)
    );
end component;


-- input signals
signal eoc:    std_ulogic := '1';
signal data:   std_ulogic_vector(15 downto 0) := x"ABAB";

-- signals
signal rst: std_ulogic := '0';
signal clk: std_ulogic := '0';

signal ADC_Data: std_ulogic_vector(15 downto 0);
begin
    Conversion_end: process
    begin
        wait until convst = '1';
        wait for 500 NS;
        eoc <= '0';
    ADC_Data <= x"ABCD";
        wait for 50 NS;
        eoc <= '1';
    end process;

    data <= ADC_Data when eoc = '0' else (others => 'Z');        

    max11046: max11046_interface
        port map (
            i_clk       => clk,
            i_rst_asyn  => '1',
            i_rst_syn   => rst,
            o_cs        => cs,
            o_wr        => wr,
            o_rd        => rd,
            o_convst    => convst,
            o_shdn      => shdn,
            i_eoc       => eoc,
            io_data      => data
        );

 end architecture_max11046_interface_tb;

He eliminado una parte del código para que sea más fácil de leer. Mi pregunta es que puede estar mal. ¿No puedo manejar la señal interna de múltiples fuentes? En el diseño lo estoy haciendo así con puertos y está funcionando:

data <= ADC_Data when eoc = '0' else (otros => 'Z');

cuando no estoy escribiendo en el puerto, está en alta impedancia y puedo leer datos.

PD: no quiero usar std_logic_vector en lugar de std_ulogic_vector.

¿Está haciendo referencia a todas las bibliotecas requeridas? "No resuelto" me sugiere que el compilador no puede averiguar el tipo exacto de data.

Respuestas (3)

Está intentando crear una señal de tres estados en 'datos' de tipo std_ulogic_vector sin resolver. El 'no resuelto' significa que no utiliza una función de resolución al establecer el valor de una señal (es decir, una 'señal' o 'puerto').

Una función de resolución toma el valor de cada una de las fuentes en una señal y las resuelve todas en un solo valor de asignación.

Entonces, el tipo de datos sin resolver que ha seleccionado solo permite una fuente, por definición. La solución es usar un tipo resuelto porque maneja múltiples fuentes en una sola señal, que es lo que quería implementar.

Los tipos típicos resueltos aquí son std_logic y std_logic_vector en su lugar. (No explica por qué no quiere usarlos, solo que no lo hace).

Por cierto, los valores iniciales de sus señales no constituyen otra fuente. Son solo valores con los que su simulador comenzará en las señales. En su ausencia, su simulador pondría 'U's en las señales que tiene.

Como pequeña corrección: la resolución resuelve múltiples fuentes, no controladores. Solo se pueden resolver señales (eso incluye puertos, porque los puertos son señales)
Gracias @Paebbels, solucionado. Sin embargo, se mantuvieron los puertos distinguidos de las señales, más claros para OP.

La explicación TL;DR

Múltiples controladores requieren resolución para determinar el valor efectivo de una señal.

IEEE Std 1076-2008 6.4.2.3 Declaraciones de señales , párrafo 8:

Una señal puede tener una o más fuentes . Para una señal de tipo escalar, cada fuente es un controlador (ver 14.7.2) o un puerto de salida , entrada , salida, búfer o enlace de una instancia de componente o de una declaración de bloque con la que está asociada la señal. Para una señal de tipo compuesto, cada fuente compuesta es una colección de fuentes escalares, una para cada subelemento escalar de la señal. Es un error si, después de la elaboración de una descripción, una señal tiene múltiples fuentes y no es una señal resuelta.. También es un error si, después de la elaboración de una descripción, una señal resuelta tiene más fuentes que el número de elementos en el rango del índice del tipo del parámetro formal de la función de resolución asociada a la señal resuelta.

las fuentes hacen que la resolución sea jerárquica -

13 Unidades de diseño y su análisis , 13.1 Unidades de diseño , párrafo 1:

Ciertas construcciones se analizan de forma independiente y se insertan en una biblioteca de diseño; estas construcciones se denominan unidades de diseño . Una o más unidades de diseño en secuencia componen un archivo de diseño .

Un componente que se instancia representa un bloque externo (3.1), una unidad de diseño se compone de una cláusula de contexto (que puede estar vacía) y una unidad de biblioteca, ya sea una unidad primaria (p. ej., declaración de entidad) o una unidad secundaria (p. ej., una arquitectura correspondiente). ).

No puede determinar todos los controladores reales hasta la elaboración. Los puertos son señales por este motivo.

14.7.3 Propagación de valores de señal , 14.7.3.1 General , párrafo 5:

El proceso kernel determina dos valores para ciertas señales durante ciertos ciclos de simulación. El valor impulsor de una señal determinada es el valor que esa señal proporciona como fuente de otras señales. El valor efectivo de una señal dada es el valor que se obtiene evaluando una referencia a la señal dentro de una expresión. El valor impulsor y el valor efectivo de una señal no siempre son los mismos, especialmente cuando las funciones de resolución y las funciones de conversión o las conversiones de tipo están involucradas en la propagación de los valores de la señal.

Una señal de puerto proporciona el valor efectivo para todas las fuentes (controladores y puertos de modo de salida, entrada y salida, búfer o enlace) que contribuyen al valor efectivo de esa señal de puerto. Los puertos se pueden leer o evaluar al resolver el valor de una red elaborada:

6.5.2 Objetos de interfaz , párrafo 9 y 10 (en parte):

Un objeto de interfaz proporciona un canal de comunicación entre el entorno y una parte particular de una descripción. El valor de un objeto de interfaz puede estar determinado por el valor de un objeto o expresión asociada en el entorno; De manera similar, el valor de un objeto en el entorno puede estar determinado por el valor de un objeto de interfaz asociado. La forma en que se realizan tales asociaciones se describe en 6.5.7.

Se dice que el valor de un objeto se lee cuando se cumple una de las siguientes condiciones:

— Cuando se evalúa el objeto, y también (indirectamente) cuando el objeto está asociado con un objeto de interfaz de los modos in , inout o linkage .

...

La clave aquí es que hay múltiples controladores (múltiples fuentes) en datasu banco de pruebas:

14.7.2 Conductores , párrafo 1:

Cada declaración de asignación de señal en una declaración de proceso define un conjunto de controladores para ciertas señales escalares. Hay un solo controlador para una señal escalar dada S en una declaración de proceso, siempre que haya al menos una declaración de asignación de señal en esa declaración de proceso y que el prefijo estático más largo de la señal de destino de esa declaración de asignación de señal denota S o denota un señal compuesta de la cual S es un subelemento. Se dice que cada declaración de asignación de señal está asociada con ese controlador. La ejecución de una declaración de asignación de señal afecta solo a los controladores asociados.

14.2 Elaboración de una jerarquía de diseño , párrafo 1:

La elaboración de una jerarquía de diseño crea una colección de procesos interconectados por redes; esta colección de procesos y redes se puede ejecutar para simular el comportamiento del diseño.

y las sentencias concurrentes (incluidos los bloques internos y externos) se elaboran como sentencias en bloque y/o sentencias en bloque y procesos (11. Sentencias concurrentes). Se garantiza que la asignación de señales tendrá lugar en una declaración de proceso, se requiere resolución con múltiples fuentes .

Eso requiere tipos de datos resueltos con funciones de resolución.

4.6 Funciones de resolución , párrafo 1:

Una función de resolución es una función que define cómo los valores de múltiples fuentes de una señal determinada se resolverán en un solo valor para esa señal. Las funciones de resolución se asocian con señales que requieren resolución incluyendo el nombre de la función de resolución en la declaración de la señal o en la declaración del subtipo de la señal. Una señal con una función de resolución asociada se denomina señal resuelta (véase 6.4.2.3).

6.4.2.3 Declaraciones de señales , párrafo 3:

Si aparece una indicación de resolución en la indicación de subtipo en la declaración de una señal o en la declaración del subtipo utilizado para declarar la señal, entonces cada función de resolución en el subtipo se asocia correspondientemente con la señal declarada o con un subelemento de la señal declarada . Tal señal o subelemento se denomina señal resuelta .

Para los elementos std_logic o std_logic, la función de resolución se proporciona en el paquete std_logic_1164 en la declaración del subtipo std_logic. std_ulogic (el tipo de elemento de std_ulogic_vector) no es un tipo resuelto.

Todo esto se reduce a no poder usar std_ulogic_vector como el tipo para datael que requiere un tipo de elemento resuelto.

También te faltan declaraciones para las señales convst, cs, wr, rdy shdn.

@TonyM No podría estar completamente de acuerdo contigo. Std_ulogic_vector o std_ulogic es una señal no resuelta, pero podría trabajar con ella como en el código

data <= ADC_Data when eoc = '0' else (others => 'Z');   

cuando no se usa como salida, estará en alta impedancia y no habrá problemas con la resolución.

De esta forma el usuario sabe exactamente lo que está haciendo. En synopsys synplify no habrá problema con la síntesis si el código se escribe así.

Corrígeme si me equivoco, pero estaba usando std_ulogic así y funcionaba bien.

Como dijiste, los valores iniciales son solo para simulación.

Una herramienta de síntesis que no lo tratara como un error no cumpliría con el estándar VHDL y podría carecer de portabilidad. También puede notar que hay una asignación datade 'Z' en la expresión agregada en el banco de pruebas (usado para simulación). Su respuesta tal vez debería ser un comentario?
No pude comentar los comentarios de otras personas, aún con un puntaje de reputación bajo :) ¡Gracias por su respuesta!
No es cierto, vuelva a leer la definición de la función de resolución. En VHDL, la alta impedancia (es decir, Z) es una fuente y múltiples fuentes requieren resolución. La pregunta de OP fue sobre un error dado por ModelSim, no por Synplify. ¿Lo has probado en ModelSim? Votación negativa.