Come posso eseguire il debug dei segnali rossi in ModelSIM?


11

Devo progettare una macchina a stati usando solo porte NAND per la parte combinatoria e le infradito D per la logica sequenziale. Tutto dovrebbe funzionare a un clock di 1ghz / 53.

Ora, prima che mi assalti con "non faremo i compiti per te", lascia che ti dica che ho demolito tutto dopo aver investito giorni di lavoro e ho iniziato a fare tutto in modo più rigoroso. Voglio farlo da solo, ma ricevo costantemente segnali casuali indefiniti nelle parti più semplici del progetto ed è frustrante.

Ok, quindi prima di tutto ho la macchina dello stato e la tabella della verità che ho fatto per essa nella seguente immagine:

Diagramma macchina a stati e tabella verità per esso

La prossima cosa sono i kmaps:

I Kmaps

Poiché per le infradito D D = Q +, il cablaggio della logica combinatoria (una volta che l'ho inserito in un blocco semplificato) non dovrebbe essere troppo difficile.

Ma il mio primo problema sorge nel banco di prova per Q3 +. Vorrei mettere qui per semplificare le informazioni un diagramma veloce che ho messo insieme per Q3 +:

Diagramma logico per Q3 +

Più avanti nel post vedrai che in VHDL ho effettivamente chiamato gli ingressi da 1Q3plus a in11Q3plus (11 ingressi), poiché questo non è il blocco finale (il blocco logico combinatorio finale è costituito dai quattro blocchi Q3 +, Q2 +, Q1 +, Q0 + cablati ai segnali).

Quindi ho dovuto realizzare tutto usando i cancelli NAND, questo significa che dovevo adottare un approccio strutturale. Ogni gate si basa fondamentalmente su porte NAND e quindi si sviluppa in complessità (ma solo le porte AND, OR e NOT sono strutturalmente scritte da porte NAND). Ho quindi una porta OR con 3 ingressi, una porta AND con 3 ingressi e una porta OR con 5 ingressi (come nell'esempio del diagramma logico), ciascuno basato sui precedenti 2 ingressi AND & OR.

Ogni banco prova fino a quello Q3plus (il diagramma sopra) ha funzionato. La mia procedura per il test consiste nell'emettere segnali per ciascun ingresso, in modo tale da poter comodamente guardare i segnali nella finestra di simulazione. Ad esempio, ho i seguenti segnali per un gate AND a 3 ingressi:

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 le connessioni sarebbero così:

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

Quindi il problema sorge quando voglio simulare il banco prova Q3plus. Sembra che si verifichi un errore in cui è meno previsto, in un segnale di test che passa da 0 a 1 con un periodo di 2 ns: |. Pubblicherò qui il codice del banco di prova, affermando ancora una volta che ogni altro banco di prova del cancello ha funzionato perfettamente:

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 il codice per il blocco Q3plus effettivo è:

 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;

Il banco prova produce il seguente risultato:

simulazione banco di prova

Come puoi vedere, il primo segnale ha un comportamento strano, i segnali successivi funzionano bene e l'ultimo acceso è completamente indefinito. Naturalmente il segnale finale, l'uscita, è difettoso.

La mia semplice domanda sarebbe: come posso tracciare dove il segnale inizia a essere danneggiato? Mi sento un noob totale in questo casino di un programma e voglio davvero finirlo. Grazie in anticipo per qualsiasi risposta.


1
Ottima presentazione delle domande. Mentre Modelsim può consentire 18nsche sia specificamente illegale nello standard VHDL e rimarrà tale. Esistono due elementi lessicali separati: letterale 18e identificativo astratti ns. Vedi IEEE Std 1076-2008 15.3 Elementi lessicali, separatori e delimitatori, par. 4 - "... È richiesto almeno un separatore tra un identificatore o un letterale astratto e un identificatore adiacente o letterale astratto". Avresti potuto scrivere il tuo stimolo come un processo usando il tempo incrementale nelle dichiarazioni di attesa. Potrebbe aver puntato direttamente al segnale non pilotato.
user8352,

Potete per favore approfondire la parte dello stimolo? Penso che quello che hai detto sia qualcosa che ho anche cercato molto, ma non ho trovato nulla: gli avvisi che ogni mio banco di prova produce. Vuoi dire che dovrei digitare uno spazio tra 18 e ns ? modifica Verificato, questo era il problema.
Azurium,

Risposte:


9

Bello vedere un banco di prova e un codice adeguati che corrispondano effettivamente alla domanda per un cambiamento ...

Esistono due semplici modi per danneggiare un segnale:

  • guidarlo da diverse fonti di segnale
  • non guidarlo da nessuno

Ora A11 rimane "U", suggerendo che non ha driver. Mentre A1 si alterna tra valori validi e 'X' non validi, suggerendo che ha più di un driver.

Con questo in mente, rivedi il tuo codice dove guidi A1 e A11.

Riderai ...

Per espandere la parte "come eseguire il debug" della domanda: dopo aver destato il sospetto che i segnali non fossero guidati dalle fonti previste, è possibile utilizzare il comando "drivers" di Modelsim per elencare i driver su un segnale. Se avessi scritto un VHDL un po 'più prolisso ed etichettato ogni processo, ciò ti avrebbe dato la stessa risposta senza dover rivedere il tuo codice ...

per esempio

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

2
Tutta quella frustrazione accumulata per ore scoppiò in una bella risata. Inoltre, mi merito un bel pugno in faccia. Il banco di prova sembra funzionare ora!
Azurium,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.