Die eine der beiden in eine eigene Beschreibung ausgelagerten Funktionseinheiten ist das Interface zum PC in der Datei pc_if.vhd.
Wie aus dem Blockschaltbild des PC-Interface (3.3.2) hervorgeht, umfaßt
es folgende Komponenten:
Nachfolgend sind obige Punkte in der Reihenfolge ihres erstmaligen Erscheinens
in der VHDL-Beschreibung erläutert.
Die Beschreibung findet sich in pc_if.vhd im zwischen den Marken
"--- Diverse Logik Anfang ---" und "--- Diverse Logik
Ende ---".
Dieser Abschnitt enthält diverse konkurrente Zuweisungen an Signale, die meistens von den Zuständen der Automaten abhängig sind. Während die Automaten also die für einen Befehl typische Folge von Zuständen durchlaufen, generieren diese Logiken (die -Schaltnetze der Automaten) die Signale, die die eigentlichen Aktionen hervorrufen und die Befehle durch ihre Auswirkungen separieren.
Wegen der Einfachheit der meisten dieser Zuweisungen sei hier nur auf
die ausführlichen Kommentare der VHDL-Quelle verwiesen.
Die Beschreibung findet sich in pc_if.vhd im Prozeß ZUSTAENDE_PUFFERN.
Wie man 3.5.1 entnehmen kann, fragen beide Automaten des PC-Interface sich zu bestimmten Zeitpunkten gegenseitig ab. Um Fehler durch sich während der Abfrage ändernde Zustandsbits auszuschließen, werden selbige Bits nicht direkt abgefragt, sondern zwei Puffer, in denen mit der Rückflanke der aktuelle Automatenzustand abgelegt wurde.
Damit kann auch hier die saubere Aufgabentrennung der Taktflanken eingehalten
werden: Automaten nähren sich von der Vorderflanke, alle von ihnen abhängigen
oder -gefragten speichernden Elemente (hier also status_reg, counter, konf_reg,
sstep_pulse_ff, progr_dclk, c_state_buffer, c_state2_buffer, i_reg) agieren
mit der Rückflanke; siehe hierzu auch Kap. 2.3.5.2 Taktung der Prozesse
- Fehlervermeidung).
Die Beschreibung findet sich in pc_if.vhd im Prozeß IREG.
Die Abarbeitung eines über das PC-Interface gesandten Befehls im Hilfs-FPGA orientiert sich an dem Vorbild existierender CPUs. In einem Wartezustand (hier: wait_for_event) wird auf das Anliegen einer gültigen Instruktion gewartet (hier signalisiert durch m_obf '0'), woraufhin der Automat in einen allgemein fetch genannten Zustand fortschreitet, in welchem er den Wert der Instruktion für die weitere Bearbeitung speichert. Es folgt ein meist decode genannter Zustand, in dem die Instruktion ausgewertet wird, d.h. es wird je nach Befehl zu unterschiedlichen Bearbeitungssträngen verzweigt, die alle wieder zu wait_for_event zurückführen.
Das Instruktionsregister i_reg ist nun dasjenige, welches im Hilfs-FPGA
den Wert der aktuellen Instruktion, also die acht Bits von pc_if_data_in,
speichert. Dies erfolgt natürlich, wenn sich der erste Automat im Zustand
fetch befindet, und zwar mit der Rückflanke (der erste Automat schreitet
ja mit der Vorderflanke fort).
Die Beschreibung findet sich in pc_if.vhd im Prozeß KONFIGURATIONS_REGISTER.
Die FPGA-Bausteine der Altera FLEX8000-Familie bieten mehrere Modi an, um sie mit einer bestimmten Logik zu programmieren. Um Pins am Hilfs-FPGA einzusparen, wurde für das Prozessor-FPGA die sogenannte passive serielle Konfiguration gewählt. Wie der Name andeutet, werden die Konfigurationsdaten dabei nur bitseriell übertragen; um die Konfiguration aber desweiteren möglichst schnell über das langsame PC-Interface abzuwickeln, sollte dessen Breite von acht Bit ausgenutzt werden (wird jeweils acht Nutzbits das Befehlsbyte für Config Data vorangesendet, bedeutet dieses einen Protokoll-Overhead von 50%, was wesentlich besser ist, als nur ein Nutzbit durch ein Byte anzukündigen, also mit einem Overhead von 89% zu arbeiten). Damit wurde das Konfigurationsregister konf_reg notwendig, welches je acht vom PC gesendete Konfigurations-Bits aufnimmt und diese bitweise an den Prozessor weitergibt (es gilt progr_data konf_reg[0]).
Es handelt sich hier um ein mit der Rückflanke gesteuertes 8 Bit-Schieberegister mit den Funktionen Laden, Schieben und Speichern.
Das Konfigurationsregister tritt bei einem Config Data in Aktion - dieser
Befehl durchläuft die Zustände config_waitf, config_fetch und anschließend
achtmal abwechselnd config_rise und config_fall. In config_waitf wird auf
ein Byte mit Konfigurationsdaten gewartet, dieses in config_fetch in konf_reg
geladen. Im Folgezustand config_rise wird sich progr_dclk mit der Rückflanke
auf '1' erheben, was zur Folge hat, daß der aktuelle Wert von progr_data
in das FPGA übernommen werden wird. Folgerichtig wird in config_fall die
Programmierclock ebenfalls mit der Rückflanke wieder auf '0' absinken;
zusätzlich aber wird zu diesem Zeitpunkt das Konfigurationsregister um
eine Stelle nach rechts geschoben werden (konf_reg[0] konf_reg[1] etc.).
Auf diese Art wird das gesamte Byte an das FPGA übergeben werden.
Die Beschreibung findet sich in pc_if.vhd im Prozeß STATUS_REGISTER.
Dieses mit der Rückflanke aktualisierte Register enthält in vier Bereichen
wichtige Informationen; die Bits des status_reg bedeuten:
Stelle | Wert: Bedeutung |
7 | '1': Hilfs-FPGA wartet auf m_halt_ack vom Mikroprozessor |
6 | '1': Hilfs-FPGA wartet auf m_reg_ack vom Mikroprozessor |
5, 4 | "00": Mikroprozessor läuft (running)
"10": Mikroprozessor wurde angehalten (halted) "11": Mikroprozessor ist im Single-Step-Modus |
3 | '1': Unbekanntes Kommando aufgetreten |
2 | '1': Ein Kommando war im damaligen Modus (running/halted/single step) nicht erlaubt |
1, 0 | "00": Konfiguration war erfolgreich
"01": Signal progr_conf_done kam noch nicht "10": Signal progr_conf_done kam zu früh "11": Ein allgemeiner Konfigurationsfehler ist aufgetreten (Signal progr_m_status = '0') |
Die Bits 4 bis 7 werden ständig neu gesetzt.
Die Bits 2 und 3 werden nur durch Report Status zurückgesetzt.
Die Bits 1 und 0 werden durch Config Start auf "01" gesetzt.
Das Auslesen des Statusregisters ist immer erlaubt, auch wenn das Hilfs-FPGA auf m_halt_ack oder m_reg_ack wartet.
Der Wert nach einem Reset ist "00000001" (Kein Warten, Mikroprozessor
läuft, keine unzulässigen Kommandos, progr_conf_done kam noch nicht).
Das genaue Vorgehen bei dem Setzen der einzelnen Bits sollte aus der
VHDL-Beschreibung ausreichend hervorgehen.
Die Beschreibung findet sich in pc_if.vhd im Prozeß INTERFACE_BUS.
Wie oben ausgeführt, muß das Hilfs-FPGA an den PC wahlweise den Inhalt
des Statusregisters oder den gepufferten Wert von Adreß- bzw. Datenbus
senden können, d.h. status_reg[7..0], areg_muxout[19..0] und dreg_muxout[15..0]
müssen achtbitweise auf das Ausgangssignal pc_if_data_out[7..0] geschaltet
werden können. Dies erfolgt in Abhängigkeit von den Zuständen des ersten
Automaten so:
Übertragen von | Vorkommen | Zustände erster Automat | aufgeschaltetes Byte |
gepufferter Adresse | Überwachen des Prozessors
Lesen von Prozessorregistern |
areg_hi
areg_mid_wait |
areg_muxout[19..16] (mit führenden Nullen erweitert) |
areg_mid
areg_lo_wait |
areg_muxout[15..8] | ||
areg_lo
read_mem_hi_wait |
areg_muxout[7..0] | ||
gepufferten Daten | Überwachen des Prozessors
Lesen des Speichers |
read_mem_hi
read_mem_lo_wait |
dreg_muxout[15..8] |
Lesen von Prozessorregistern | read_mem_lo
read_mem_lo_hold |
dreg_muxout[7..0] | |
Statusbits | Abfrage von Wartezuständen, Laufmodus, aufgetretenen Fehlern und Konfigurationsergebnis | bericht_send
bericht_clear |
status_reg[7..0] |
Im jeweils ersten Zustand eines Paares in der Spalte "Zustände erster Automat" ist m_stb am Schnittstellenbaustein 8255 '0', d.h. dessen Input Buffer latcht die Daten von pc_if_data; zwischen diesen Daten und m_stb ist aber eine Haltezeit notwendig, so daß im jeweils zweiten Zustand die Daten zwar weiterhin anliegen, m_stb aber wieder inaktiv ist.
Das status_reg ändert sich bereits wieder mit der Rückflanke im Zustand bericht_clear (wie der Name schon sagt), dies reicht für die Haltezeit jedoch aus.
In den Zuständen mit Namenspostfix _wait wird zusätzlich abgefragt, ob das zuletzt gesendete Byte schon aus dem Input Buffer abgeholt worden ist.
Sollen Adresse und Datum übertragen werden, werden die Zustände von areg_hi bis read_mem_lo_hold wie in der dritten Spalte aufgeführt durchlaufen; wird nur das Datum benötigt, beginnt der Vorgang bei read_mem_hi.
Die Beschreibung findet sich in pc_if.vhd im Prozeß ZAEHLER.
Dies ist ein Zähler von 0 bis (maximal) 8 für drei Verwendungszwecke:
Die Beschreibung findet sich in pc_if.vhd in den Prozessen
KONTROLLE, ACK_KONTROLLE und SYNCH.
Die zwei endlichen Automaten des PC-Interface dienen dazu, die Funktionalität
des Interfaces zwischen PC und Hilfs-FPGA zur Verfügung zu stellen, ergo
die in 2.2.2 genannten Kommandos zu erkennen und entsprechende Aktionen
durchzuführen. Um ihre Funktionsweise grundlegend zu verstehen, muß man
die wichtigsten Fakten kennen:
Die momentane Zulässigkeit eines Befehles ist abhängig von diesem Modus.
Beide Automaten werden mit der Vorderflanke getaktet, die Startzustände lauten wait_for_event und warten. Die Abfrage des Zustands des jeweils anderen Automaten erfolgt gepuffert durch c_state_buffer bzw. c_state2_buffer (Aktualisierung mit Rückflanke).
Die Abläufe in den Automaten und ihre Abhängigkeit voneinander finden
sich visualisiert in Kapitel 3.5.1 Automaten im PC-Interface. Zur weiteren
Erklärung der Details sei auf den ausführlich dokumentierten Code verwiesen.
Besonders in der Testphase von Prozessor-Designs, Hilfs-FPGA
und PC-Software war es möglich, daß eine bestimmte Form der Verklemmung
auftrat. Dabei sendet bei einem Handshaking-Protokoll die eine Seite ein
initiierendes Signal aus, oder meint, dieses zu tun, und wartet anschließend
auf das entsprechende affirmative Signal, ohne dieses jedoch zu empfangen.
Um solche Verklemmungen zu vermeiden, war es notwendig, sich zu überlegen,
daß in der Kontrollhierarchie PC Hilfs-FPGA Mikroprozessor sechs Vorgänge
in dieser Hinsicht kritisch sind:
Wie können diese Verklemmungen, die in der Praxis leicht dazu führen
können, schwerwiegende Entwurfsfehler zu vermuten, da eine Komponente offenbar
nicht (mehr) reagiert, aufgelöst werden, und was sind ihre Ursachen?
1. (PC sendet Byte)
Mögliche Ursachen: Da das Hilfs-FPGA stets m_obf abfragt, wenn es einen Befehl zu Ende abgearbeitet hat, was ja nur eine Frage der Zeit ist, muß es selbst auf ein Signal warten. Da weiterhin aber das Warten auf m_halt_ack und m_reg_ack wegen der Fälle 5. und 6. nunmehr parallel zum Auslesen des Schnittstellenbausteines durchgeführt wird, bleibt nur ein Warten auf ibf = '0' als Ursache, d.h. das Hilfs-FPGA soll ein Byte empfangen, möchte aber selbst gerade eines senden, was nicht möglich ist, da bereits ein nicht-abgeholtes Byte im Schnittstellenbaustein wartet. Ursache kann nur ein Irrtum bei der Abstimmung der Software im PC mit dem PC-Interface im Hilfs-FPGA sein, d.h. Senden eines falschen Befehlswortes, welches eine Antwort bedingt, mit der nicht gerechnet wird, oder Irrtum über die Anzahl zurückgelieferter Bytes.
Lösung: Mit einem timer ist in der PC-Software leicht
der Zeitpunkt abzuwarten, an dem der längstmögliche Befehl im Hilfs-FPGA
abgearbeitet worden sein müßte (Config Start durchläuft sieben Zustände
in 21 Takten). Wurde das Byte danach immer noch nicht abgeholt, so kann
nur eine Verklemmung wegen Wartens auf ibf vorliegen (zu der anderen möglichen
Ursache "Totalabsturz des Hilfs-FPGAs" siehe 2.4.4). Es müssen
nun nur sukzessive solange Bytes aus dem Schnittstellenbaustein ausgelesen
werden, bis ibf nicht mehr auf '1' geht, d.h. das Hilfs-FPGA nicht mehr
sendet. Diese Lösung hat im Gegensatz zum Senden eines Hardware-Resets
an das Hilfs-FPGA den Vorteil, daß das Statusregister hernach noch nicht
gelöscht wurde.
2. (Hilfs-FPGA erwartet Byte)
Mögliche Ursachen: Irrtümer bei der Abstimmung von Software im PC mit PC-Interface im Hilfs-FPGA.
Lösung: Dieser Fehler ist nur indirekt durch "Verschwinden"
von Befehlen/Daten zu entdecken. Wartet das Hilfs-FPGA nämlich noch auf
ein Byte, so wird natürlich auch ein Report-Befehl, der die Lage klären
sollte, als das fehlende Datum genommen. Bei Befehlen aus mehreren Bytes,
z.B. Store Data, können Hilfs-FPGA und PC auch quasi desynchronisiert werden,
so daß das eigentliche Befehlsbyte noch irgendwelche Lücken stopft, ein
nachfolgendes Datenbyte aber als Befehl interpretiert wird, was sich irgendwann
als aufgetretener illegaler oder momentan nicht zulässiger Befehl im Statusregister
erraten läßt. Ein Reset für das Hilfs-FPGA erscheint dann angebracht.
3. (Hilfs-FPGA sendet Byte)
Mögliche Ursachen: Dies ist die andere Sicht des Falles 1., siehe dort.
Lösung: Siehe 1. .
4. (PC erwartet Byte)
Mögliche Ursachen: Irrtümer bei der Abstimmung von Software im PC mit PC-Interface im Hilfs-FPGA; Irrtum bezüglich des Lauf-Modus, in dem sich Prozessor und Hilfs-FPGA befinden. Letzterer Fall bedeutet, daß ein an das Hilfs-FPGA gerichteter Befehl deswegen keine Bytes zurückliefert, weil er im momentanen Modus (z.B. running) des Hilfs-FPGAs gar nicht erlaubt ist und somit ignoriert wird (aber das Statusregister beeinfluÿt).
Lösung: Auf jeden Fall sollte man einen Report-Befehl senden,
um zu überprüfen, ob der angenommene Modus des Hilfs-FPGAs auch tatsächlich
der aktuelle ist. Ist dieses der Fall und der gewünschte Befehl tatsächlich
zulässig, bleiben die Irrtümer der ersten Art als Erklärung.
5. (Hilfs-FPGA wartet auf m_halt_ack)
Mögliche Ursachen: Anhalten des Prozessors fehlerhaft implementiert; m_halt ändert sich zu kurz.
Lösung: Um auch bei fehlerhafter/noch nicht vorhandener Implementierung
des Haltevorganges das Hilfs-FPGA weiter benutzen zu können, wurde das
Warten auf die Bestätigung durch m_halt_ack parallel zu der Abarbeitung
der anderen Befehle des PC-Interfaces, insbesondere Report und Abort, verwirklicht.
Ein sinnloser Wartezustand kann so bei Ablauf eines timers mit Report
festgestellt und mit Abort abgebrochen werden. Ein längeres Haltesignal
wird durch das Kommando halt1 möglich.
6. (Hilfs-FPGA wartet auf m_reg_ack)
Mögliche Ursachen: Auslesefähigkeit für Register fehlerhaft implementiert.
Lösung: Um auch bei fehlerhafter/noch nicht vorhandener Implementierung
des Auslesevorganges das Hilfs-FPGA weiter benutzen zu können, wurde das
Warten auf die Bestätigung durch m_reg_ack parallel zu der Abarbeitung
der anderen Befehle des PC-Interfaces, insbesondere Report und Abort, verwirklicht.
Ein sinnloser Wartezustand kann so bei Ablauf eines timers mit Report
festgestellt und mit Abort abgebrochen werden.
Die Fälle 1. bis 4. können lediglich über Software erkannt werden (der 2. auch nur mit Mühen). Dies erklärt die Entwurfsentscheidung, "nur" die letzten beiden Fälle (Warten auf m_halt_ack oder m_reg_ack) durch parallele Verarbeitung in der Hardware zu entschärfen.