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:
Lo siguiente son 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+:
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:
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.
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:
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
usuario8352
18ns
, es específicamente ilegal en el estándar VHDL y seguirá siéndolo. Hay dos elementos léxicos separados, literal abstracto18
e identificadorns
. 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.azurio