Ich muss eine Zustandsmaschine entwerfen, die nur NAND-Gatter für den kombinatorischen Teil und D-Flip-Flops für die sequentielle Logik verwendet. Alles sollte mit einer Uhr von 1 GHz / 53 laufen.
Bevor Sie mich jetzt mit "Wir machen Ihre Hausaufgaben nicht für Sie" angreifen, möchte ich Ihnen sagen, dass ich alles verschrottet habe, nachdem ich Tage Arbeit investiert habe, und alles wieder strenger gemacht habe. Ich möchte dies alleine tun, aber ich erhalte ständig zufällige undefinierte Signale in den einfachsten Teilen des Projekts und es ist frustrierend.
Ok, also zuerst habe ich die Zustandsmaschine und die Wahrheitstabelle, die ich dafür gemacht habe, im folgenden Bild:
Das nächste sind die kmaps:
Da für D-Flip-Flops D = Q + ist, sollte die Verdrahtung der kombinatorischen Logik (sobald ich sie in einen vereinfachten Block eingebaut habe) nicht zu schwierig sein.
Aber mein erstes Problem tritt im Prüfstand für Q3 + auf. Lassen Sie mich hier zur Vereinfachung der Informationen ein schnelles Diagramm einfügen, das ich für Q3 + zusammengestellt habe:
Später in diesem Beitrag werden Sie sehen, dass ich in VHDL die Eingänge in1Q3plus bis in11Q3plus (11 Eingänge) benannt habe, da dies nicht der letzte Block ist (der letzte kombinatorische Logikblock besteht aus den vier verdrahteten Blöcken Q3 +, Q2 +, Q1 +, Q0 + zu Signalen).
Also musste ich alles mit NAND-Gates machen, das heißt, ich musste einen strukturellen Ansatz verfolgen. Jedes Gate basiert im Wesentlichen auf NAND-Gates und baut sich dann in seiner Komplexität auf (aber nur AND-, OR- und NOT-Gates werden strukturell aus NAND-Gates geschrieben). Ich habe dann ein ODER-Gatter mit 3 Eingängen, ein UND-Gatter mit 3 Eingängen und ein ODER-Gatter mit 5 Eingängen (wie im Beispiel des Logikdiagramms), die jeweils auf den vorherigen UND-ODER-Gattern mit 2 Eingängen basieren.
Jeder Prüfstand bis zum Q3plus (siehe Abbildung oben) funktionierte. Mein Testverfahren besteht darin, Signale für jeden Eingang zu erstellen, sodass ich die Signale im Simulationsfenster bequem beobachten kann. Zum Beispiel habe ich die folgenden Signale für ein UND-Gatter mit 3 Eingängen:
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;
Und die Verbindungen würden so aussehen:
u1:ANDgate3 port map(A=>a1, B=>b1, C=>c1, fand3=>q1 );
Das Problem tritt also auf, wenn ich den Q3plus-Prüfstand simulieren möchte. Es scheint, dass ich einen Fehler habe, bei dem er am wenigsten erwartet wird, bei einem Testsignal, das nur mit einer Periode von 2 ns von 0 auf 1 wechselt: |. Ich werde hier den Code des Prüfstands veröffentlichen und noch einmal feststellen, dass jeder andere Gate-Prüfstand einwandfrei funktioniert hat:
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;
Und der Code für den eigentlichen Q3plus-Block lautet:
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;
Der Prüfstand liefert folgendes Ergebnis:
Wie Sie sehen können, hat das erste Signal ein merkwürdiges Verhalten, die nächsten Signale funktionieren einwandfrei und das letzte ist völlig undefiniert. Natürlich ist das endgültige Signal, der Ausgang, fehlerhaft.
Meine einfache Frage wäre: Wie kann ich verfolgen, wo das Signal beschädigt wird? Ich fühle mich wie ein absoluter Noob in diesem Durcheinander eines Programms, und ich möchte das wirklich beenden. Vielen Dank im Voraus für jede Antwort.
quelle
18ns
es im VHDL-Standard ausdrücklich illegal ist und dies auch bleiben wird. Es gibt zwei separate lexikalische Elemente: abstraktes Literal18
und Bezeichnerns
. Siehe IEEE Std 1076-2008 15.3 Lexikalische Elemente, Trennzeichen und Trennzeichen, Abs. 4 - ".... Es ist mindestens ein Trennzeichen zwischen einem Bezeichner oder einem abstrakten Literal und einem benachbarten Bezeichner oder einem abstrakten Literal erforderlich." Sie hätten Ihren Stimulus als einen Prozess mit inkrementeller Zeit in Warteanweisungen schreiben können. Möglicherweise hat es direkt auf das nicht gesteuerte Signal hingewiesen.Antworten:
Schön, eine richtige Testbench und einen Code zu sehen, die zur Abwechslung tatsächlich der Frage entsprechen ...
Es gibt zwei einfache Möglichkeiten, ein Signal zu beschädigen:
Jetzt bleibt A11 durchgehend 'U', was darauf hindeutet, dass es keinen Fahrer hat. Während A1 zwischen gültigen und 'X' ungültigen Werten wechselt, deutet dies darauf hin, dass es mehr als einen Treiber hat.
Überprüfen Sie in diesem Sinne Ihren Code, in dem Sie A1 und A11 fahren.
Du wirst lachen ...
Um den Teil "Wie man debuggt" der Frage zu erweitern: Nachdem Sie den Verdacht geweckt haben, dass Signale nicht von den erwarteten Quellen stammen, können Sie den Befehl "drivers" von Modelsim verwenden, um die Treiber für ein Signal aufzulisten. Wenn Sie etwas ausführlicheres VHDL geschrieben und jeden Prozess beschriftet hätten, würden Sie dieselbe Antwort erhalten, ohne Ihren Code überprüfen zu müssen ...
z.B
quelle