Comment déboguer les signaux rouges dans ModelSIM?

11

Je dois concevoir une machine à états utilisant uniquement des portes NAND pour la partie combinatoire et des bascules D pour la logique séquentielle. Tout devrait fonctionner à une horloge de 1 GHz / 53.

Maintenant, avant de m'agresser avec "nous ne ferons pas vos devoirs pour vous", permettez-moi de vous dire que j'ai tout abandonné après avoir investi des jours de travail et recommencé à tout faire plus rigoureusement. Je veux le faire moi-même, mais je reçois constamment des signaux aléatoires non définis dans les parties les plus simples du projet et c'est frustrant.

Ok, donc tout d'abord j'ai la machine d'état et la table de vérité que j'ai faite pour cela dans l'image suivante:

Diagramme de la machine d'état et table de vérité pour celui-ci

La prochaine chose sont les kmaps:

Les Kmaps

Puisque pour les bascules D D = Q +, le câblage de la logique combinatoire (une fois que je l'ai construit en un bloc simplifié) ne devrait pas être trop difficile.

Mais mon premier problème se pose dans le banc d'essai pour Q3 +. Permettez-moi de mettre ici pour simplifier les informations un diagramme rapide que j'ai mis en place pour Q3 +:

Diagramme logique pour Q3 +

Plus tard dans la publication, vous verrez qu'en VHDL, j'ai en fait nommé les entrées in1Q3plus à in11Q3plus (11 entrées), car ce n'est pas le bloc final (le dernier bloc logique combinatoire se compose des quatre blocs Q3 +, Q2 +, Q1 +, Q0 + câblés aux signaux).

J'ai donc dû tout faire en utilisant des portes NAND, ce qui signifie que j'ai dû adopter une approche structurelle. Chaque porte est essentiellement basée sur des portes NAND, puis elle s'accumule en complexité (mais seules les portes ET, OU et NON sont écrites structurellement à partir des portes NAND). J'ai ensuite une porte OU avec 3 entrées, une porte ET avec 3 entrées et une porte OU avec 5 entrées (comme dans l'exemple du diagramme logique), chacune basée sur les 2 portes ET et OU précédentes.

Chaque banc d'essai jusqu'à celui du Q3plus (le diagramme ci-dessus) a fonctionné. Ma procédure de test consiste à émettre des signaux pour chaque entrée, de sorte que je puisse facilement regarder les signaux dans la fenêtre Simulation. Par exemple, j'ai les signaux suivants pour une porte ET à 3 entrées:

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;

Et les connexions ressembleraient à ceci:

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

Le problème se pose donc lorsque je veux simuler le banc d'essai Q3plus. Il semble que j'ai une erreur là où on s'y attend le moins, sur un signal de test qui bascule de 0 à 1 avec une période de 2ns: |. Je posterai ici le code du banc de test, déclarant une fois de plus que tous les autres bancs de test de porte ont fonctionné parfaitement:

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;

Et le code du bloc Q3plus réel est:

 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;

Le banc d'essai produit le résultat suivant:

simulation de banc d'essai

Comme vous pouvez le voir, le premier signal a un comportement étrange, les signaux suivants fonctionnent bien et le dernier est complètement indéfini. Bien sûr, le signal final, la sortie, est défectueux.

Ma question simple serait: comment puis-je savoir où le signal commence à être corrompu? Je me sens comme un noob total dans ce gâchis d'un programme, et je veux vraiment terminer cela. Merci d'avance pour toute réponse.

Azurium
la source
1
Très bonne présentation des questions. Bien que Modelsim puisse permettre 18nsqu'il soit spécifiquement illégal dans la norme VHDL et le restera. Il existe deux éléments lexicaux séparés littéral 18et identifiant ns. Voir IEEE Std 1076-2008 15.3 Éléments lexicaux, séparateurs et délimiteurs, par. 4 - ".... Au moins un séparateur est requis entre un identifiant ou un littéral abstrait et un identifiant ou littéral abstrait adjacent". Vous auriez pu écrire votre stimulus comme un seul processus en utilisant le temps incrémentiel dans les instructions d'attente. Il peut avoir pointé directement le signal non piloté.
user8352
Pouvez-vous développer la partie stimulus? Je pense que ce que vous avez dit est quelque chose que j'ai aussi beaucoup cherché mais que je n'ai rien trouvé: les avertissements que chaque banc d'essai produit. Voulez-vous dire que je devrais taper un espace entre 18 et ns ? modifier Vérifié, c'était le problème.
Azurium

Réponses:

9

Ravi de voir un banc de test et un code appropriés qui correspondent réellement à la question d'un changement ...

Il existe deux façons simples de corrompre un signal:

  • le conduire à partir de plusieurs sources de signaux
  • ne le conduisez pas

Maintenant, A11 reste «U» partout, ce qui suggère qu'il n'a pas de pilote. Alors que A1 alterne entre des valeurs valides et «X» non valides, ce qui suggère qu'il a plus d'un pilote.

Dans cet esprit, passez en revue votre code où vous conduisez A1 et A11.

Tu vas rire ...

Pour développer la partie "comment déboguer" de la question: ayant suscité un soupçon que les signaux n'étaient pas pilotés à partir des sources attendues, vous pouvez utiliser la commande "drivers" de Modelsim pour répertorier les pilotes sur un signal. Si vous aviez écrit un VHDL un peu plus verbeux et étiqueté chaque processus, cela vous donnerait la même réponse sans avoir à revoir votre code ...

par exemple

Drive_A1 : process
begin
   a1 <= '0' ; wait for 4ns;
   ... etc
Brian Drummond
la source
2
Toute cette frustration qui s'est accumulée pendant des heures a éclaté de rire. Je mérite aussi une bonne claque sur mon visage. Le banc d'essai semble fonctionner maintenant!
Azurium