¿Cómo depuro las señales rojas en ModelSIM?

Tengo que diseñar una máquina de estado usando solo puertas NAND para la parte combinatoria y flip flops D para la lógica secuencial. Todo debería funcionar a un reloj de 1ghz/53.

Ahora, antes de que me agredas con "no te haremos la tarea", déjame decirte que deseché todo después de invertir días de trabajo y comencé a hacer todo de nuevo con más rigor. Quiero hacer esto por mi cuenta, pero constantemente recibo señales aleatorias indefinidas en las partes más simples del proyecto y es frustrante.

Bien, primero que nada tengo la máquina de estado y la tabla de verdad que hice para ella en la siguiente imagen:

Diagrama de máquina de estado y tabla de verdad para ello

Lo siguiente son los kmaps:

Los Kmaps

Dado que para D flip flops D=Q+, el cableado de la lógica combinatoria (una vez que lo construyo en un bloque simplificado) no debería ser demasiado difícil.

Pero mi primer problema surge en el banco de pruebas del Q3+. Permítanme poner aquí para simplificar la información un diagrama rápido que preparé para Q3+:

Diagrama lógico para Q3+

Más adelante en la publicación, verá que en VHDL nombré las entradas in1Q3plus a in11Q3plus (11 entradas), ya que este no es el bloque final (el bloque lógico combinatorio final consta de los cuatro bloques Q3+, Q2+, Q1+, Q0+ cableados a las señales).

Así que tuve que hacer todo usando puertas NAND, lo que significa que tuve que adoptar un enfoque estructural. Cada puerta se basa básicamente en puertas NAND, y luego se acumula en complejidad (pero solo las puertas AND, OR y NOT se escriben estructuralmente a partir de puertas NAND). Luego tengo una puerta OR con 3 entradas, una puerta AND con 3 entradas y una puerta OR con 5 entradas (como en el ejemplo del diagrama lógico), cada una basada en las 2 puertas AND&OR de entrada anteriores.

Todos los bancos de prueba hasta el Q3plus (el diagrama de arriba) funcionaron. Mi procedimiento de prueba es generar señales para cada entrada, de modo que pueda ver las señales en la ventana de Simulación de manera conveniente. Por ejemplo, tengo las siguientes señales para una puerta AND de 3 entradas:

process
    begin
a1 <= '0' ; wait for 4ns;
a1 <= '1' ; wait for 4ns;
end process;

process
    begin
b1 <= '0' ; wait for 8ns;
b1 <= '1' ; wait for 8ns;
end process;

process
    begin
c1 <= '0' ; wait for 2ns;
c1 <= '1' ; wait for 2ns;
end process;

Y las conexiones se verían así:

u1:ANDgate3 port map(A=>a1, B=>b1, C=>c1, fand3=>q1 );

Entonces el problema surge cuando quiero simular el banco de pruebas Q3plus. Parece que tengo un error donde menos se esperaba, en una señal de prueba que cambia de 0 a 1 con un período de 2 ns :|. Publicaré aquí el código del banco de pruebas, indicando una vez más que todos los demás bancos de pruebas de puertas funcionaron sin problemas:

library ieee;
use ieee.std_logic_1164.all;

entity Q3plusTEST is
end Q3plusTEST;

architecture behavior of Q3plusTEST is
    component Q3plus is
    port(outQ3plus: out std_Logic;
    in1Q3plus: in std_Logic;
    in2Q3plus: in std_Logic;
    in3Q3plus: in std_Logic;
    in4Q3plus: in std_Logic;
    in5Q3plus: in std_Logic;
    in6Q3plus: in std_Logic;
    in7Q3plus: in std_Logic;
    in8Q3plus: in std_Logic;
    in9Q3plus: in std_Logic;
    in10Q3plus: in std_Logic;
    in11Q3plus: in std_Logic);
    end component;

signal a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11, outsignal: std_logic;

begin
    process
    begin
        a1<= '0'; wait for 4ns;
        a1<= '1'; wait for 4ns;
    end process;

    process
    begin
        a2<= '0'; wait for 6ns;
        a2<= '1'; wait for 6ns;
    end process;

    process
    begin
        a3<= '0'; wait for 8ns;
        a3<= '1'; wait for 8ns;
    end process;

    process
    begin
        a4<= '0'; wait for 10ns;
        a4<= '1'; wait for 10ns;
    end process;

    process
    begin
        a5<= '0'; wait for 12ns;
        a5<= '1'; wait for 12ns;
    end process;

    process
    begin
        a6<= '0'; wait for 14ns;
        a6<= '1'; wait for 14ns;
    end process;

    process
    begin
        a7<= '0'; wait for 16ns;
        a7<= '1'; wait for 16ns;
    end process;

    process
    begin
        a8<= '0'; wait for 18ns;
        a8<= '1'; wait for 18ns;
    end process;

    process
    begin
        a9<= '0'; wait for 20ns;
        a9<= '1'; wait for 20ns;
    end process;

    process
    begin
        a10<= '0'; wait for 22ns;
        a10<= '1'; wait for 22ns;
    end process;

    process
    begin
        a1<= '0'; wait for 24ns;
        a1<= '1'; wait for 24ns;
    end process;

    U1: Q3plus port map(in1Q3plus=> a1, in2Q3plus=>a2, in3Q3plus=>a3, in4Q3plus=>a4, in5Q3plus=>a5, in6Q3plus=>a6, in7Q3plus=>a7, in8Q3plus=>a8, in9Q3plus=>a9, in10Q3plus=>a10, in11Q3plus=>a11, outQ3plus=> outsignal); end behavior;

Y el código para el bloque Q3plus real es:

 library ieee;
use ieee.std_logic_1164.all;

entity Q3plus is
    port(outQ3plus: out std_Logic;
    in1Q3plus: in std_Logic;
    in2Q3plus: in std_Logic;
    in3Q3plus: in std_Logic;
    in4Q3plus: in std_Logic;
    in5Q3plus: in std_Logic;
    in6Q3plus: in std_Logic;
    in7Q3plus: in std_Logic;
    in8Q3plus: in std_Logic;
    in9Q3plus: in std_Logic;
    in10Q3plus: in std_Logic;
    in11Q3plus: in std_Logic);
    end Q3plus;

architecture behavior of Q3plus is
    component ORgate5 is
    port(AOR5: in std_logic;
    BOR5: in std_logic;
    COR5: in std_logic;
    DOR5: in std_logic;
    EOR5: in std_logic;
    f5or: out std_logic);
    end component;

    component ANDgate3 is
    port(A: in std_logic;
    B: in std_logic;
    C: in std_logic;
    fand3: out std_logic);
    end component;

    component ANDgate is
    port(xand: in std_logic;
    yand: in std_logic;
    fand: out std_logic);
    end component;

signal z1,z2,z3,z4,z5: std_logic;

begin
    U1: ANDgate port map(xand=> in1Q3plus, yand=> in2Q3plus, fand=> z1);
    U2: ANDgate port map(xand=> in3Q3plus, yand=> in4Q3plus, fand=> z2);
    U3: ANDgate port map(xand=> in5Q3plus, yand=> in6Q3plus, fand=> z3);
    U4: ANDgate port map(xand=> in7Q3plus, yand=> in8Q3plus, fand=> z4);
    U5: ANDgate3 port map(A=> in9Q3plus, B=> in10Q3plus, C=> in11Q3plus, fand3=> z5);
-- urmeaza toate portile de mai sus conectate la OR5
    U6: ORgate5 port map(AOR5=>z1, BOR5=> z2, COR5=> z3, DOR5=> z4, EOR5=> z5, f5or=> outQ3plus);

end behavior;

El banco de pruebas produce el siguiente resultado:

simulación de banco de pruebas

Como puede ver, la primera señal tiene un comportamiento extraño, las siguientes señales funcionan bien y la última está completamente indefinida. Por supuesto, la señal final, la salida, es defectuosa.

Mi simple pregunta sería: ¿cómo puedo rastrear dónde comienza a corromperse la señal? Me siento como un novato total en este lío de programa, y ​​realmente quiero terminar esto. Gracias de antemano por cualquier respuesta.

Muy buena presentación de preguntas. Si bien Modelsim puede permitirlo 18ns, es específicamente ilegal en el estándar VHDL y seguirá siéndolo. Hay dos elementos léxicos separados, literal abstracto 18e identificador ns. Ver IEEE Std 1076-2008 15.3 Elementos léxicos, separadores y delimitadores, párr. 4 - "... . Se requiere al menos un separador entre un identificador o literal abstracto y un identificador adyacente o literal abstracto". Podría haber escrito su estímulo como un proceso utilizando el tiempo incremental en declaraciones de espera. Puede haber apuntado directamente a la señal no impulsada.
¿Puedes dar más detalles sobre la parte del estímulo? Creo que lo que dijiste es algo que también busqué mucho pero no encontré nada: las advertencias que produce cada banco de pruebas. ¿Quiere decir que debo escribir un espacio entre 18 y ns ? editar Verificado, ese era el problema.

Respuestas (1)

Es bueno ver un banco de pruebas y un código adecuados que realmente coincidan con la pregunta para variar ...

Hay dos maneras fáciles de corromper una señal:

  • conducirlo desde varias fuentes de señal
  • no lo conduzcas desde ningún

Ahora A11 sigue siendo 'U' en todo momento, lo que sugiere que no tiene controlador. Mientras que A1 alterna entre valores válidos y 'X' no válidos, lo que sugiere que tiene más de un controlador.

Con eso en mente, revise su código donde maneja A1 y A11.

Te vas a reir...

Para ampliar la parte de la pregunta "cómo depurar": habiendo despertado la sospecha de que las señales no se generaron desde las fuentes esperadas, podría usar el comando "controladores" de Modelsim para enumerar los controladores en una señal. Si hubiera escrito VHDL un poco más detallado y etiquetado cada proceso, obtendría la misma respuesta sin tener que revisar su código...

p.ej

Drive_A1 : process
begin
   a1 <= '0' ; wait for 4ns;
   ... etc