Como depurar sinais vermelhos no ModelSIM?


11

Eu tenho que projetar uma máquina de estado usando apenas portas NAND para a parte combinatória e chinelos D para a lógica seqüencial. Tudo deve funcionar com um relógio de 1ghz / 53.

Agora, antes de me agredir com "não faremos o dever de casa por você", deixe-me dizer que acabei com tudo depois de investir dias de trabalho e comecei a fazer tudo de novo com mais rigor. Quero fazer isso sozinho, mas recebo constantemente sinais indefinidos aleatórios nas partes mais simples do projeto e é frustrante.

Ok, então, primeiro, tenho a máquina de estado e a tabela de verdade que fiz na imagem a seguir:

Diagrama da máquina de estado e Tabela da verdade para ele

A próxima coisa são os kmaps:

The Kmaps

Como nos chinelos D, D = Q +, a fiação da lógica combinatória (uma vez que eu a construo em um bloco simplificado) não deve ser muito difícil.

Mas meu primeiro problema surge no banco de testes do Q3 +. Deixe-me colocar aqui para simplificar as informações, um diagrama rápido que eu montei para o terceiro trimestre:

Diagrama Lógico para Q3 +

Posteriormente, você verá que, em VHDL, na verdade, nomeei as entradas in1Q3plus como in11Q3plus (11 entradas), já que este não é o bloco final (o bloco lógico combinatório final consiste nos quatro blocos Q3 +, Q2 +, Q1 +, Q0 + conectados) sinais).

Então eu tive que fazer tudo usando portas NAND, isso significa que eu tive que ter uma abordagem estrutural. Todo portão é basicamente baseado em portas NAND, e depois se desenvolve em complexidade (mas apenas as portas AND, OR e NOT são escritas estruturalmente a partir das portas NAND). Em seguida, tenho uma porta OR com 3 entradas, uma porta AND com 3 entradas e uma porta OR com 5 entradas (como no exemplo do diagrama lógico), cada uma baseada nas 2 portas anteriores AND & OR anteriores.

Cada bancada de testes até a Q3plus (o diagrama acima) funcionou. Meu procedimento para testar é emitir sinais para cada entrada, para que eu possa assistir convenientemente os sinais na janela Simulação. Por exemplo, tenho os seguintes sinais para uma porta 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;

E as conexões ficariam assim:

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

Portanto, o problema surge quando quero simular a bancada de testes do Q3plus. Parece que tenho um erro onde é menos esperado, em um sinal de teste que apenas muda de 0 para 1 com um período de 2ns: |. Vou postar aqui o código da bancada de testes, mais uma vez afirmando que todas as outras bancadas de testes funcionavam perfeitamente:

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;

E o código para o bloco Q3plus real é:

 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;

A bancada de testes produz o seguinte resultado:

simulação de banco de ensaio

Como você pode ver, o primeiro sinal tem um comportamento estranho, os próximos sinais funcionam bem e o último ligado é completamente indefinido. Obviamente, o sinal final, a saída, está com defeito.

Minha pergunta simples seria: como rastrear onde o sinal começa a ficar corrompido? Eu me sinto um noob total nessa bagunça de programa, e eu realmente quero terminar isso. Agradeço antecipadamente qualquer resposta.


1
Apresentação de pergunta muito boa. Embora o Modelsim possa permitir 18nsque seja especificamente ilegal no padrão VHDL, continuará sendo. Existem dois elementos lexicais separados, literal 18e identificador ns. Ver IEEE Std 1076-2008 15.3 Elementos, separadores e delimitadores léxicos, par. 4 - ".... É necessário pelo menos um separador entre um identificador ou um literal abstrato e um identificador adjacente ou literal abstrato". Você poderia ter escrito seu estímulo como um processo usando instruções incrementais de tempo em espera. Pode ter apontado diretamente para o sinal não acionado.
User8352

Você pode elaborar a parte do estímulo? Acho que o que você disse é algo que também procurei bastante, mas não encontrei nada: os avisos que todos os meus testes produzem. Você quer dizer que eu deveria digitar um espaço entre 18 e ns ? editar Verificado, esse foi o problema.
Azurium

Respostas:


9

É bom ver um código de teste e um código adequados que realmente correspondam à pergunta de mudança ...

Existem duas maneiras fáceis de corromper um sinal:

  • conduza-o de várias fontes de sinal
  • não dirija de qualquer

Agora, o A11 permanece 'U' o tempo todo, sugerindo que não possui driver. Enquanto A1 alterna entre valores válidos e 'X' inválidos, sugerindo que ele tenha mais de um driver.

Com isso em mente, revise seu código onde você dirige A1 e A11.

Você vai rir ...

Para expandir a parte "como depurar" da pergunta: após ter levantado a suspeita de que os sinais não eram direcionados pelas fontes esperadas, você poderia usar o comando "drivers" do Modelsim para listar os drivers em um sinal. Se você tivesse escrito VHDL um pouco mais detalhado e rotulado cada processo, você obteria a mesma resposta sem precisar revisar seu código ...

por exemplo

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

2
Toda essa frustração acumulada por horas explodiu em uma boa risada. Também mereço um tapa no rosto. O banco de testes parece estar funcionando agora!
Azurium
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.