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

11

Tengo que diseñar una máquina de estados usando solo compuertas 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 asaltes con "no haremos tu tarea por ti", déjame decirte que descarté 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 indefinidas al azar en las partes más simples del proyecto y es frustrante.

Ok, antes que nada tengo la máquina de estado y la tabla de verdad que hice para ello 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 para 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 en realidad 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 + conectados) a las señales).

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

Cada banco de pruebas hasta el Q3plus (el diagrama de arriba) funcionó. Mi procedimiento para probar es hacer señales para cada entrada, de modo que pueda ver cómodamente las señales en la ventana de Simulación. 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 espera, en una señal de prueba que simplemente cambia de 0 a 1 con un período de 2ns: |. Publicaré aquí el código del banco de pruebas, una vez más indicando que todos los demás bancos de pruebas de la puerta 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 la señal comienza a corromperse? Me siento como un novato total en este desastre de un programa, y ​​realmente quiero terminar esto. Gracias de antemano por cualquier respuesta.

Azurio
fuente
1
Muy buena presentación de preguntas. Si bien Modelsim puede permitir 18nsque sea específicamente ilegal en el estándar VHDL y lo seguirá siendo. 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 un literal abstracto y un identificador adyacente o literal abstracto". Podría haber escrito su estímulo como un proceso usando tiempo incremental en declaraciones de espera. Puede haber apuntado a la señal no dirigida directamente.
user8352
¿Puedes por favor elaborar sobre la parte de estímulo? Creo que lo que dijiste es algo que también busqué mucho pero no encontré nada: las advertencias que producen todos mis bancos de pruebas. ¿Quiere decir que debería escribir un espacio entre 18 y ns ? editar Verificado, ese era el problema.
Azurium

Respuestas:

9

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

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

  • conducirlo desde varias fuentes de señal
  • no lo conduzcas desde ninguna

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

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

Te vas a reir...

Para ampliar la parte de "cómo depurar" la pregunta: al haber suscitado la sospecha de que las señales no provenían de las fuentes esperadas, puede utilizar el comando "controladores" de Modelsim para enumerar los controladores en una señal. Si hubiera escrito un 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
Brian Drummond
fuente
2
Toda esa frustración que se acumuló durante horas estalló en una buena carcajada. También merezco una buena bofetada en la cara. ¡El banco de pruebas parece estar funcionando ahora!
Azurium