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:
La prochaine chose sont 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 +:
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:
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.
la source
18ns
qu'il soit spécifiquement illégal dans la norme VHDL et le restera. Il existe deux éléments lexicaux séparés littéral18
et identifiantns
. 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é.Réponses:
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:
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
la source