Vorheriger AbschnittNächster AbschnittInhaltsverzeichnis

2.3 Aufbau und Arbeitsweise der Funktionseinheiten

2.3.1 Das Top-Level-Design "ctrl_pur.vhd"

Um die für das Hilfs-FPGA zu generierende Hardware maschinell verwertbar zu beschreiben, wurde die standardisierte Hardware-Beschreibungssprache VHDL (Very high speed integrated circuit Hardware Description Language) benutzt. Diese unterstützt hierarchische Entwürfe; wegen ihres Umfanges und der thematischen Abgeschlossenheit bot es sich dabei an, das Interface zum PC und die Ansteuerung des 20x2-Zeichen-Displays in eigenständige, untergeordnete Beschreibungen auszulagern und diese auf der höchsten Ebene zu referenzieren. Diese höchste Ebene findet sich in der Datei ctrl_pur.vhd.

Wie aus dem Blockschaltbild des Hilfs-FPGAs (3.3.1) hervorgeht, verbleiben folgende Komponenten im Top-Level-Design:

Nachfolgend sind obige Punkte in der Reihenfolge ihres erstmaligen Erscheinens in der VHDL-Beschreibung erläutert.

Das Protokoll für den User Mode des Displays

Die Beschreibung findet sich in ctrl_pur.vhd zwischen den Marken

"--- Display Anfang ---" und "--- Display Ende ---".

Folgende Operationen sind auf dem memory mapped arbeitenden Display für den Mikroprozessor möglich:

Adressbits

19 … 4

Adressbits

3 … 0

Datenbit

0

Zugriffsart

Wirkung

**1* 1 Schreiben user_mode_set '1', d.h. Display geht in User Mode, Anzeige von Adr. u. Datum stoppt.
9000 - **1* 0 Schreiben user_mode_reset '1', d.h. Display beendet User Mode, Adr. u. Datum werden wie gewohnt angezeigt, falls eines gültig anliegt.
97FF

(Adressbereich

**00 * Schreiben user_disp_go '0'; Display beginnt, falls im User Mode, mit der Anzeige von user_char, ansonsten keine Wirkung.
Display) **00 user_disp_busy Lesen Display berichtet, ob noch mit Zeichenanzeige beschäftigt (user_disp_busy = '1').
**01 * Schreiben Speichern der unteren neun Datenbits in user_char (disp_rs und eigentliches Zeichen).


Die Tastatur-Ansteuerung

Die Beschreibung findet sich in ctrl_pur.vhd zwischen den Marken

"--- Tastatur Anfang ---" und "--- Tastatur Ende ---".

Zur Funktionalität: Zusammenfassend gesagt wird mit jedem Takt genau eine Spalte der Tastenmatrix per Schieberegister tast_spalte_t (tast_spalte) aktiviert, die Rückantwort (auf tast_reihe) ausgewertet, das tast_reg entsprechend gesetzt und eventuell ausgegeben sowie nachfolgend gelöscht.

Die "Hex-Tastatur" mit 20 Tasten ist als Matrix von einfachen Schaltern (Drucktaster) mit 5 Spalten und 4 Reihen realisiert. Die Eingänge aller Schalter einer Spalte hängen an tast_spalte(x), die Ausgänge führen in jeder Zeile auf tast_reihe(y). Keine zwei Schalter sind also mit Ein- und Ausgang an den gleichen Signalen angeschlossen. Nun wird durch tast_spalte immer genau eine Spalte mit '1' getrieben, alle anderen mit '0'. Meldet eine Reihe durch '1', daß in ihr eine Taste gedrückt wird, so muß es sich um diejenige Taste handeln, die in der gerade getriebenen Spalte liegt.

Falls mehrere Tasten gleichzeitig gedrückt werden sollten, könnte es bei diesem Aufbau zu Kurzschlüssen zwischen zwei Spalten kommen. Deswegen werden die fünf Spaltensignale zwischen Hilfs-FPGA und Tastaturmatrix durch Schutzdioden in Durchlaßrichtung geführt, welche die Nullen nicht durchlassen; es trifft also immer '1' auf 'Z' (Leitung offen), was sicher wieder '1' ergibt.

Damit das Drücken einer Taste in der gerade aktivierten Spalte sich von dem in einer anderen Spalte bzw. keinem Tastendruck unterscheidet, damit also '1' und 'Z' an tast_reihe unterschiedlich aussehen, wurde tast_reihe mit Pull Down-Widerständen versehen, die aus 'Z' eine (schwache) '0' machen.

Das ringförmige Schieberegister tast_spalte_t enthält immer genau eine Eins und rotiert mit jeder Taktrückflanke um eine Stelle (Prozeß TASTATUR_ANSTEUERUNG); tast_spalte wird direkt aus tast_spalte_t abgeleitet.

Mit der Vorderflanke wird (im Prozeß TASTATUR_REGISTER), das tast_reg modifiziert, welches mit seinen zwanzig Bits widerspiegelt, welche Tasten seit dem letzten Löschen (durch Auslesen) gedrückt worden sind. In nachstehender Reihenfolge werden Bedingungen überprüft und gegebenenfalls Veränderungen durchgeführt:

  1. Wird gerade aus dem Adreßbereich der Tastatur gelesen? Falls ja, können bei einer geraden Adresse die unteren 16 Bits des tast_reg, sonst der Rest, zum Löschen vorgesehen werden. Das Lesen aus dem Adreßbereich der Tastatur wird nämlich asynchron auch von dem Prozeß BUSSE überwacht, der bei Eintreten dieser Bedingung "sofort" den Datenbus mit einer "Hälfte" des tast_reg treibt, so daß dieses vom Mikroprozessor abgefragt werden kann.

Die ungleichen Hälften des tast_reg werden durch Setzen von tast_reg_clear(0/1) als zu löschen markiert.

  1. Soll eine Hälfte des tast_reg initialisiert werden, d.h. ist tast_reg_clear(0/1) '1'? Das Löschen findet statt, falls dieses der Fall ist und m_oe '1' ist, womit gewährleistet wird, daß der Lesevorgang nicht noch andauert. Wird gelöscht, so wird auch das korrespondierende Bit aus tast_reg_clear zurückgesetzt.
  1. Wurde eine Taste gedrückt? Nur falls die ersten beiden Bedingungen nicht eintreten, kann ein Bit im tast_reg auf '1' gesetzt werden. Dazu existiert für jedes Bit eine Logik der Form

tast_reg(x) (tast_reihe(a) AND tast_spalte_t(b)) OR tast_reg(x);

Das ODER-Gatter sorgt durch Verknüpfung mit dem alten Wert dafür, daß eine '1' stets erhalten bleibt (gelöscht wird ja durch den separaten Vorgang des Auslesens). Die mit UND verknüpften Signale sind quasi die Koordinaten einer Taste in der Matrix; eine bestimmte Taste wird genau dann gerade gedrückt, wenn ihr Reihenausgang '1' liefert und ihre Spalte gerade getrieben wird.

Folgende Operationen sind auf der memory mapped arbeitenden Tastatur für den Mikroprozessor also möglich:

Adressbits

19 … 4

Adressbits

3 … 0

Datenbits

15 …0

Zugriffsart

Wirkung

9800 - 9FFF

(Adressbereich Tastatur)

***0 tast_reg(15 downto 0) Lesen Untere "Hälfte" von tast_reg wird auf Datenbus gelegt und mit der nächsten Vorderflanke, zu der m_oe wieder '1' ist (Lesen beendet), gelöscht.
***1 "ZZZZZZZZZZZZ" &

tast_reg(19 downto 16)

Lesen Analog für obere "Hälfte" von tast_reg.


Der Takt für den Mikrorechner: clk1_democom, clk2_democom

Die Beschreibung findet sich in ctrl_pur.vhd zwischen den Marken

"--- Tastatur Ende ---" und "--- Synchronisation Anfang ---" und lautet dort:

clk1_democom clk AND clk_aktiv; -- Democom bekommt Takt wie Hilfs-FPGA,

-- maskiert mit

clk2_democom NOT (clk AND clk_aktiv); -- clk_aktiv aus dem PC-Interface.

Das Signal clk_aktiv wird in pc_if.vhd aus dem Statusregister und dem sstep_pulse_ff abgeleitet; der Mikroprozessor wird mit einem Taktsignal versorgt, falls er

  1. "normal" laufen soll (Modus running),
  2. angehalten ist (Modus halted; der Mikrorechner hält "freiwillig" als Reaktion auf m_halt  '0') oder
  3. sich im Einzelschritt-Betrieb befindet (Modus single step) und eben einen solchen Einzelschritt durchführen soll. Dazu geht sstep_pulse_ff für einen Takt von Rückflanke zu Rückflanke auf '1' und clk_aktiv folgt ihm nach.

Um Funktions-Hazards auf dem Taktsignal für den Mikrorechner auszuschließen, ändern sich status_reg und sstep_pulse_ff, und damit auch clk_aktiv, mit der Rückflanke; letzteres hat sich also rechtzeitig vor der bevorzugt benutzten Vorderflanke stabilisiert. Wie man sich leicht überlegen kann, ist auch der Verlauf der Rückflanke für den Mikroprozessor aller Wahrscheinlichkeit nach unkritisch; drei Fälle sind dabei zu unterscheiden:

  1. clk ändert sich vor clk_aktiv (extrem wahrscheinlich wegen einerseits der Durchlaufzeiten der Flipflops und Logik, andererseits Verwendung der Clock-Netze der Altera FLEX8000-Bausteine, siehe Kap. 2.3.5.2 Taktung der Prozesse - Fehlervermeidung), die erzeugte Rückflanke kommt zum "richtigen" Zeitpunkt. Sollte clk_aktiv nachher noch "zappeln", bleibt dies, wegen des schon deaktivierten UND-Gatters, ohne Auswirkung.
  2. clk_aktiv geht vor clk auf '0' und behält diesen Wert bei, bis auch clk '0' wird; die erzeugte Rückflanke kommt maximal einige Nanosekunden "zu früh" - unkritisch.
  3. clk_aktiv geht vor clk auf '0' und wieder auf '1' zurück - ein Hazard tritt auf bevor das UND-Gatter durch clk deaktiviert wird. Dieses Verhalten könnte tatsächlich zu einem "beschleunigten Takt" führen, ist aber wegen 1. praktisch ausgeschlossen.

Die Busfreigabe: m_highz

Die Beschreibung findet sich in ctrl_pur.vhd zwischen den Marken

"--- Tastatur Ende ---" und "--- Synchronisation Anfang ---" und lautet dort:

m_highz m_highz_t;

m_highz_t '0' when ((mem_read = '1') OR (mem_write = '1')) else '1';

Jedes Design eines Mikroprozessors muß, falls das Hilfs-FPGA den Speicher beeinflussen und kontrollieren können soll, folgende Signale freigeben können, d.h. nicht mehr treiben: Adreßbus (address), Datenbus (databus), Output Enable (m_oe), Write Enable (m_we).

Diese Funktionalität wurde deswegen in die Datei altera1500.tdf integriert, die Grundlage jedes Prozessorentwurfs sein muß, u.a. um gleiche Pinbelegungen sicherzustellen. Wird das Steuersignal m_highz auf '0' gezogen, so werden die oben genannten Signale asynchron und ohne Einflußmöglichkeit des Prozessors mittels Tri-State-Treibern vom Rest des Mikroprozessorboards getrennt.

Das temporäre Signal m_highz_t wird verwendet, da m_highz in der VHDL-Beschreibung als Ausgang definiert ist, wodurch es nicht mehr möglich ist, seinen Wert abzufragen. Genau dieses passiert aber in der RAM-Zugriffsmaschine, die ja für einen Lese- oder Schreibzyklus m_oe und m_we steuern muß, sie aber natürlich erst treiben darf, wenn die Signale "frei" sind.

Die "Mem"-Signale originieren im PC-Interface und initiieren einen Speicherzugriff, indem die RAM-Steuerungsmaschine ihren Wartezustand verläßt (siehe hierzu Kap. 3.5 Abhängigkeiten der Automaten). Das PC-Interface läßt die Aussendung beider Signale nur im Zustand halted zu.

Die Logik mittendrin: a_or_d_changed und pc_if_data

Die Beschreibung findet sich in ctrl_pur.vhd zwischen den Marken

"--- Tastatur Ende ---" und "--- Synchronisation Anfang ---" und lautet dort:

a_or_d_changed <= '1' when ((m_oe = '1') AND (m_we = '0')) OR -- Jemand schreibt in SRAM oder

((m_oe = '0') AND (m_we = '1')) OR -- jemand liest aus SRAM oder

(m_reg_ack = '0') -- Democom-Register ist da

else '0';

pc_if_data pc_if_data_out when (pc_if_driven = '1') else "ZZZZZZZZ";

-- Getrennte In-/Out-Busse wie

pc_if_data_in pc_if_data; -- in altera1500.tdf

Das Signal a_or_d_changed "erkennt" aus den typischen Wertekombinationen von m_oe und m_we einen lesenden oder schreibenden Zugriff auf den Speicher und aus dem affirmativen Signal m_reg_ack, ob der Mikroprozessor gerade den angeforderten Wert eines seiner internen Register auf Adreß- oder Datenbus legt. In allen drei Fällen hat sich der Wert mindestens eines Busses geändert, so daß als Folge areg_muxout und dreg_muxout deren Werte speichern (falls der PC diese abfragen sollte) und die Display-Ansteuerung dann mit dem Neuaufbau der Anzeige beginnt, falls sie sich nicht im User Mode befindet.

Die Synchronisation von Signalen

Die Beschreibung findet sich in ctrl_pur.vhd zwischen den Marken

"--- Synchronisation Anfang ---" und "--- Synchronisation Ende ---".

Die Signale reset_unsync, m_obf_unsync und ibf_unsync müssen vor ihrer Verwendung (als Signale ohne das Suffix "_unsync") mit dem Taktsignal für das Hilfs-FPGA synchronisiert werden. Dies geschieht in gleicher Weise mit der Taktrückflanke, indem bei deren Auftreten der momentane Wert der Signale in drei Flipflops festgehalten wird.

reset bedarf der Synchronisation, da bei einem asynchronen Zurücksetzen folgendes Szenario möglich wäre:

  1. Die Zustandsflipflops eines Automaten sollen auf einen bekannten Initialzustand zurückgesetzt werden. Hierzu wird das low-aktive Reset-Signal auf '0' gesetzt.
  2. Der Signalwechsel auf reset_unsync erreicht die Flipflops zu verschiedenen Zeitpunkten. Dies ist möglich, da durch die Verhaltensbeschreibung in VHDL absichtlich von Plazierung und Verdrahtung auf dem FPGA abstrahiert wird; der FPGA-Logikcompiler Max+plus II versucht automatisch Hardware-Strukturen zu generieren, die das spezifizierte Verhalten zeigen.
  3. Wichtig ist, daß wegen 2. höchstwahrscheinlich auch das Ende des Resets zu verschiedenen Zeitpunkten stattfindet. Außerdem ist es grundsätzlich nicht ausgeschlossen, daß Flipflops einen Reset unterschiedlich schnell ausführen.
  4. Einige Zustandsflipflops haben schon den Initialzustand angenommen und sind zur Abspeicherung eines Wertes mit der nächsten relevanten Taktflanke bereit, andere beinhalten noch einen nicht vorhersagbaren Wert und würden auf die Flanke nicht reagieren.
  5. Die Logik zur Generierung des Folgezustandes arbeitet wie immer und "errechnet" einen Folgezustand. Dies ist besonders prekär insofern, als die teilweise zurückgesetzten Zustandsflipflops eine Zustandskodierung enthalten können, die überhaupt nicht zulässig ist.
  6. Nun erfolgt die für die Zustandsübernahme relevanten Taktflanke (Rückflanke bei RAM-Steuerung, Vorderflanke sonst). Der Automat nimmt einen nicht vorhersagbaren, höchstwahrscheinlich aber nicht den Initialzustand ein.

Alle Zustandsübergangslogiken enthalten einen "when others"-Fall, so daß bei Vorliegen einer nicht erlaubten Zustandskodierung ebenfalls der Initialzustand eingenommen werden sollte. Jedoch sind zwei Ausnahmen denkbar: Erstens könnte Max+plus II während der Logiksynthese erkennen, daß dieser Fall, von reiner, nicht mit Laufzeiteffekten behafteter Logik ausgehend, ja gar nicht eintreten kann und die zu dessen Behandlung vorgesehene Logik einfach fortlassen. Zweitens blieb in der Testphase des Hilfs-FPGAs unklar, ob verbotene Zustände nur Folge oder (auch) Ursache der unerklärlichen "Abstürze" dieses Bausteines waren (siehe 2.4.4).

Die Chipselect-Logik

Die Beschreibung findet sich in ctrl_pur.vhd zwischen den Marken

"--- Chipselect Anfang ---" und "--- Chipselect Ende ---".

Diese Logik unterteilt den Speicher in überschneidungsfreie Intervalle, so daß bei einem Zugriff auf eine bestimmte Adresse höchstens ein Gerät aktiviert ist. Den Speicher teilen unter sich auf: Hauptspeicher, parallele I/O, serielle I/O, EPROM, Display, Tastatur und Mikrocode-RAM. Nur die ersten vier erhalten tatsächlich ein Chipselect-Signal, welches die entsprechenden Bausteine entweder für normalen Betrieb zur Verfügung stellt, oder so deaktiviert, als seien sie von allen Bussen abgeklemmt. Für die nächsten beiden wird ein internes Signal erzeugt, so daß das Hilfs-FPGA weiß, wann auf diese memory mapped arbeitenden Komponenten zugegriffen wurde (wobei es dann noch verschiedene Adressen zu unterscheiden gilt, siehe 2.3.1.1 für Display und 2.3.1.2 für Tastatur).

Auf das Mikrocode-RAM wird zugegriffen, indem der PC das, auf dem realen Adreßbus gar nicht vorhandene, 21. Adreßbit auf '1' setzt (welches in areg_rollin(20) gepuffert wird).

Zur Funktionalität: Der Code für alle Chipselect-Signale lautet:

if ((mem_write = '0' AND mem_read = '0') OR areg_rollin(20) = '0') then

-- Eine Komponente kann Chipselect bekommen, falls entweder das Hilfs-FPGA _nicht_ den Adressbus treibt, oder

-- es das zwar tut, aber im Bereich der I/O-Geraete (21. Adressbit ist '0').

case

(Hier werden die Chipselect-Signale für alle mit 0 beginnenden Adressen vergeben wie in der Tabelle unten)

end case;

else

chipsel "111111"; -- keine Komponente aktiv, da Adresse im Mikrocode-RAM

end if;

Hierzu muß man beachten, daß das Altera 81500-FPGA nicht nur Prozessor-Designs beherbergen darf, sondern auch das sogenannte Ladedesign. Nur mit diesem ist es möglich, das Mikrocode-RAM zu beschreiben oder auszulesen, denn dieses RAM hängt nicht an den allgemeinen Adreß- und Datenbussen, sondern direkt am 81500-FPGA. Das Ladedesign tut nichts anderes, als Adreß- und Datenbus sowie Output Enable und Write Enable durchzureichen.

Mit der Entscheidung, ob man das 21. Adreßbit setzt oder nicht gibt es somit vier Fälle:

  1. Der 81500 enthält ein Prozessor-Design und areg_rollin eine Adresse mit führender '0'. Gleichgültig, ob Prozessor oder Hilfs-FPGA den Adreßbus treiben, wird höchstens eines der ersten sechs Geräte aktiviert und kann nachfolgend bearbeitet werden. Konflikte sind nicht möglich, denn das Subdesign in pc_if.vhd erlaubt einen Schreib- oder Lesezyklus des Hilfs-FPGAs (begonnen durch eine '1' auf mem_write oder mem_read) nur dann, wenn der jeweils geladene Prozessor angehalten hat, und sobald ein solcher Zyklus beginnt, wird der Prozessor via m_highz "sofort" von den Bussen geschaltet.
  1. Der 81500 enthält ein Prozessor-Design und areg_rollin eine Adresse mit führender '1'. Solange mem_write und mem_read '0' bleiben, mit anderen Worten, solange nur der Prozessor auf den Bussen arbeitet, müssen selbstverständlich die Chipselect-Signale wie gewöhnlich erzeugt werden. Beginnt aber das Hilfs-FPGA einen Speicherzugriff, so signalisiert das 21. Adreßbit, daß dieser dem Mikrocode-RAM gilt, weswegen die Chipselect-Signale inaktiv bleiben; dieser Zugriff "verpufft" also wirkungslos.
  1. Der 81500 enthält das Ladedesign und areg_rollin eine Adresse mit führender '1'. Wieder werden bei einem Speicherzugriff des Hilfs-FPGAs keine Chipselect-Signale erzeugt, doch das Ladedesign reicht Adreß- und Datenbus mit Steuersignalen an das Mikrocode-RAM durch und dieses kann somit ausgelesen oder beschrieben werden. Das Ladedesign treibt den Adreßbus nicht.
  1. Der 81500 enthält das Ladedesign und areg_rollin eine Adresse mit führender '0'. Dieser Fall muß von der PC-Software unbedingt verhindert werden! Soll das Hilfs-FPGA unter dieser Adresse ein Datum ablegen, landet dieses, korrekt, in der unteren Speicherhälfte, aber ebenso an der korrespondierenden Stelle im Mikrocode-RAM, denn das Ladedesign beschreibt dieses ja simultan und kann den Irrtum, da das 21. Adreßbit auf dem Bus nicht existiert, nicht erkennen. Wird der Speicher gar gelesen, kann es zur Zerstörung der Hardware kommen, denn zwei Quellen treiben den Datenbus: Der eigentlich angesprochene Baustein auf dem MPB bzw. das Hilfs-FPGA, wenn Display oder Tastatur abgefragt werden und das FPGA mit dem Ladedesign, denn wieder kann dieses den Irrtum nicht erkennen.

Im Zweifelsfall empfiehlt es sich daher, den 81500 mit einem Prozessor-Design neu zu konfigurieren, wenn in die untere Speicherhälfte geschrieben werden soll und nicht ausgeschlossen werden kann, daß er noch das Ladedesign enthält.

Die Aufteilung des Speichers schlußendlich sieht also so aus:

Adreßbereich

Komponente

Chipselect geführt an Bausteine

000000 - 01FFFF SRAM IC8 RAM1, IC9 RAM0
080000 - 087FFF Parallele I/O IC12 PIO_8255
088000 - 08FFFF Serielle I/O IC13 UART-2681
090000 - 097FFF Display (Signal nur intern verwendet)
098000 - 09FFFF Tastatur (Signal nur intern verwendet)
0A0000 - 0BFFFF - -
0C0000 - 0DFFFF EPROM IC10 EPROM1, IC11 EPROM0
0E0000 - 0FFFFF - -
100000 - 1FFFFF Mikrocode-RAM IC3 RAM4, IC4 RAM3, IC5 RAM2, IC6 RAM1, IC7 RAM0



Die Multiplexer und Tri-State-Treiber für Adreß- und Datenbus

Die Beschreibung findet sich in ctrl_pur.vhd im Prozeß BUSSE.

Zur Funktionalität: Normalerweise treibt das Hilfs-FPGA die beiden Busse auf der Mikrorechnerplatine nicht, überläßt sie dem Wechselspiel von Mikrorechner und anderen Komponenten. In der VHDL-Beschreibung wird den Bussen dann ein Vektor "Z...Z" passender Länge zugewiesen.

Wenn das Hilfs-FPGA selbst "aktiv" wird, i.e. Speicher auslesen oder beschreiben möchte, wird der Adreßbus address mit dem Wert von areg_rollin beschickt, der Datenbus databus wird analog aber nur beim Schreiben mit dreg_rollin getrieben, beim Lesen wird natürlich von "draußen" ein Datenwert erwartet. In zwei anderen Fällen reagiert das Hilfs-FPGA nur "passiv" auf (unter anderem) eine bestimmte Adresse, so daß der Adreßbus in diesen Fällen selbstverständlich nicht getrieben wird. Diese beiden Fälle sind:

Erstens das Abfragen von user_disp_busy (siehe 2.3.1.1), um zu erfahren, ob das 20x2-Zeichen-Display seinen Auftrag schon erfüllt hat, ein benutzerdefiniertes Zeichen anzuzeigen. Dabei wird das niedrigstwertige Bit des Datenbusses mit user_disp_busy beschickt. Zweitens das Abfragen des tast_reg (siehe 2.3.1.2), um zu ermitteln, ob und welche Tasten gedrückt wurden. Da das tast_reg breiter als 16 Bit ist, werden entweder seine unteren 16 Bit, oder die oberen vier, wieder ergänzt durch Teile von dreg_rollin, auf den Datenbus aufgebracht.

Verwaltung der Ein-/Ausgangspuffer areg_muxout, dreg_muxout und areg_rollin, dreg_rollin

Die Beschreibung findet sich in ctrl_pur.vhd nach dem Prozeß BUSSE bis zum Dateiende (Prozesse ADRESSREGISTER, DATENREGISTER und DATENREGISTER2).

Zur Funktionalität: Die vier Register areg_muxout, dreg_muxout, areg_rollin und dreg_rollin dienen hauptsächlich der Pufferung der Busse und der Bitbreitenumsetzung zwischen PC-Interface und Mikroprozessorplatine. Ihre Anordnung und Wirkung läßt sich am kürzesten so darstellen:

Adreßbus (address) -/20 areg_muxout -/8 PC-Interface (pc_if_data)

PC-Interface (pc_if_data) -/2*4 areg_rollin -/20 Adreßbus (address)

Datenbus (databus) -/16 dreg_muxout -/8 PC-Interface (pc_if_data)

PC-Interface (pc_if_data) -/2*4 dreg_rollin -/16 Datenbus (databus)

Die "Mux-Out"-Register wirken in Richtung zum PC und sorgen dafür, daß gültige Adressen und Daten jederzeit gespeichert werden können, um sie dann byteweise zu übertragen. Adresse und Datum sind dann gültig, wenn "jemand" (i.e. der Mikrorechner oder das Hilfs-FPGA) den Speicher ausliest oder ihn beschreibt oder wenn der Mikrorechner mit m_reg_ack signalisiert, daß die Rückantwort beim Auslesen eines seiner internen Register bereitsteht; das Lesen und Schreiben im Speicher läßt sich durch die Werte von m_oe und m_we erkennen, nämlich die Kombinationen ((m_oe = '0') AND (m_we = '1')) respektive ((m_oe = '1') AND (m_we = '0')). Das Suffix "_muxout" ergibt sich daraus, daß die Registerinhalte, aus Sicht des Hilfs-FPGAs, nach "auswärts" geschickt werden und daß mit Hilfe eines Multiplexers acht der 16 bzw. 20 Bits zur Übertragung ausgewählt werden.

Die "Roll-In"-Register wirken in Gegenrichtung und akkumulieren die Bytepakete des PC-Interface zu Adressen/Daten korrekter Länge. Dabei sendet der PC zwar grundsätzlich acht Bits gleichzeitig, diese werden jedoch in zwei Takten als Pakete zu je vier Bit in das Register hineingeschoben; damit bleibt die Möglichkeit erhalten, alternativ oder additiv eine vierbittige Datenquelle, wie z.B. eine Hexadezimal-Tastatur, anzuschließen. Die Inhalte dieser Register sind zu verstehen als der "nächste zu schreibende Wert" und die "nächste anzulegende Adresse", denn will der PC eine Speicherzelle beschreiben, so sendet er drei Kommandos über das PC-Interface:

  1. Store Address (Kommandowort sta) mit nachfolgenden 3 Bytes, deren untere 20 Bits in areg_rollin gespeichert werden
  1. Store Data (Kommandowort std) mit nachfolgenden 2 Bytes, die in dreg_rollin gespeichert werden
  1. Write RAM (Kommandowort wr), woraufhin ein Schreibzyklus beginnt, bei dem die Busse mit den "Roll-In"-Registern getrieben werden.

Soll von einer Adresse gelesen werden, kann der zweite Schritt selbstverständlich fortfallen. Durch diese grundsätzliche Vorgehensweise ist es möglich, einen Speicherbereich zu initialisieren, indem man nur einmal std sendet, und nachfolgend vor jedem wr lediglich die Adresse verändert. Andererseits kann die zuletzt beschriebene Speicherzelle einen neuen Wert zugewiesen bekommen, indem man nur std (und natürlich wr) befiehlt.

Die RAM-Zugriffsmaschine

Die Beschreibung findet sich in ctrl_pur.vhd zwischen den Marken

"--- RAM Zugriffsmaschine Anfang ---" und "--- RAM Zugriffsmaschine Ende ---".

Dieser endliche Automat ist in 3.4.2 dargestellt, in 3.5.2 unter Berücksichtigung der Abhängigkeit von anderen Automaten.

Die Übernahme des Folgezustandes erfolgt mit der Rückflanke, da eine Abhängigkeit zum ersten Automaten aus dem PC-Interface besteht, welcher mit der Vorderflanke läuft. Die Beschreibung erfolgte wie üblich in zwei (parallel ablaufenden) Prozessen (ZUGRIFF und RAM_IF_SYNCH; siehe Kap. 2.3.4 "A guide to Carsten's VHDL").

Zur Funktionalität: Der Automat wartet nach Beendigung eines Schreib- oder Lesezyklus so lange, bis ihm durch write_mem '1' bzw. read_mem '1' der Auftrag für das nächste Schreiben/Lesen gegeben wird. Dieses wird durch Durchlaufen zweier Zustände erledigt, wonach der Automat wieder in den Wartezustand zurückkehrt. Der letzte Zustand eines Zyklus sendet das Signal mem_ready aus, welches wiederum der erste Automat im PC-Interface abfragt.

Ein dritter Prozeß RAM_IF_STEUERSIGNALE treibt, sobald write_mem oder read_mem auf '1' gehen, die Ausgänge m_oe (Output Enable) und m_we (Write Enable) in Abhängigkeit vom Zustand des RAM-Zugriffsautomaten. Das dabei entstehende Timing bei Lese- und Schreibvorgängen zeigen die Schaubilder 3.2.1 und 3.2.2 .


Vorheriger AbschnittNächster AbschnittInhaltsverzeichnis