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 einem Takt von 1ghz/53 laufen.
Bevor Sie mich jetzt mit "wir machen Ihre Hausaufgaben nicht für Sie" überfallen, lassen Sie mich Ihnen sagen, dass ich alles verschrottet habe, nachdem ich Tage Arbeit investiert habe, und wieder angefangen habe, alles konsequenter zu machen. Ich möchte das alleine machen, aber ich bekomme 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 im folgenden Bild gemacht habe:
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 einbaue) nicht zu schwierig sein.
Aber mein erstes Problem taucht 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 im Beitrag werden Sie sehen, dass ich in VHDL die Eingänge tatsächlich in1Q3plus bis in11Q3plus (11 Eingänge) benannt habe, da dies nicht der letzte Block ist (der letzte kombinatorische Logikblock besteht aus den vier Blöcken Q3+, Q2+, Q1+, Q0+, die verdrahtet sind zu Signalen).
Also musste ich alles mit NAND-Gattern machen, das heißt, ich musste einen strukturellen Ansatz wählen. Jedes Gatter basiert im Grunde auf NAND-Gattern und baut dann an Komplexität auf (aber nur UND-, ODER- und NICHT-Gatter werden strukturell aus NAND-Gattern 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), jeweils basierend auf den vorherigen 2-Eingangs-UND&ODER-Gattern.
Jeder Prüfstand bis zum Q3plus (das Diagramm oben) hat funktioniert. Mein Testverfahren besteht darin, Signale für jeden Eingang zu erzeugen, sodass ich die Signale bequem im Simulationsfenster 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, wo es 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 posten, der noch einmal feststellt, 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 an 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 totaler Noob in diesem Durcheinander von einem Programm, und ich möchte das wirklich beenden. Vielen Dank im Voraus für jede Antwort.
Schön, eine richtige Testbench und Code zu sehen, die zur Abwechslung tatsächlich zur Frage passen ...
Es gibt zwei einfache Möglichkeiten, wie ein Signal beschädigt werden kann:
Jetzt bleibt A11 durchgehend 'U', was darauf hindeutet, dass es keinen Treiber hat. Während A1 zwischen gültigen und 'X' ungültigen Werten wechselt, was darauf hindeutet, dass es mehr als einen Treiber hat.
Überprüfen Sie in diesem Sinne Ihren Code, wo Sie A1 und A11 fahren.
Du wirst lachen...
Um den Teil der Frage "wie man debuggt" zu erweitern: Nachdem Sie den Verdacht geweckt haben, dass Signale nicht von den erwarteten Quellen getrieben wurden, können Sie den Befehl "drivers" von Modelsim verwenden, um die Treiber auf einem Signal aufzulisten. Wenn Sie etwas ausführlicheres VHDL geschrieben und jeden Prozess beschriftet hätten, würden Sie die gleiche Antwort erhalten, ohne Ihren Code überprüfen zu müssen ...
z.B
Drive_A1 : process
begin
a1 <= '0' ; wait for 4ns;
... etc
Benutzer8352
18ns
, ist dies im VHDL-Standard ausdrücklich illegal und wird dies auch bleiben. Es gibt zwei separate lexikalische Elemente, abstraktes Literal18
und Bezeichnerns
. Siehe IEEE Std 1076-2008 15.3 Lexical elements, separators and delimiters, para. 4 - "... . Zwischen einem Bezeichner oder einem abstrakten Literal und einem angrenzenden Bezeichner oder abstrakten Literal ist mindestens ein Trennzeichen erforderlich." Sie hätten Ihren Stimulus als einen Prozess mit inkrementeller Zeit in Warteanweisungen schreiben können. Es kann direkt auf das nicht angesteuerte Signal gezeigt haben.Azurium