Aufmacher 

PCI-Recorder 

Audio-Schnittstellenkarte für den PCI-Bus, Teil 2

Martin Kirst, Uwe Kirst


[ Hauptseite | Artikel | Abbildung 8 - Listing | Lötprobleme | Stückliste ]

Zustandsmaschinen
Die Komponente 'critpath'
Die Komponente 'pipcon'
SRAM-Timing
Initiator-Wartezyklen
Die Komponente 'cfgblock'
Plug & Play ist unverzichtbar
Adreßbereich

Ein Interrupt-Impuls wird erzeugt, wenn die Audioadresse gerade eine 16-KByte-Grenze überschreitet; ein Schreibzugriff auf das Audio-Steuerregister setzt die Interruptleitung zurück. Ein Tri-State-Buffer schaltet die Interrupt-Leitung im inaktiven Zustand auf hochohmig. Mehrere Geräte können sich so eine Interrupt-Leitung teilen (wired OR). Im Audiosteuerregister zeigt das höchstwertige Bit an, ob der Interrupt von der Audiokarte erzeugt wurde.

Zustandsmaschinen

Die PLBB wurde auf Grundlage der PCI-Local-Bus-Spezifikation-2.0 entwickelt, die in ihrem Anhang B allgemeine Zustandsmaschinen für Master und Target beschreibt. Diese Zustandsmaschinen können jedoch nicht für die konkrete Implementierung übernommen werden, denn alle relevanten PCI-Signale ergeben sich kombinatorisch aus den Zuständen. Die kombinatorische Verknüpfung erhöht die 'Clock to Output'-Verzögerung in unerlaubtem Maße und steht daher nicht mehr in Übereinstimmung mit der PCI-Spezifikation.

Die Timing-Probleme bei der Erzeugung von PCI-Steuersignalen konnten durch eine Aufteilung in zwei Teile gelöst werden. Das Modul 'critpath' enthält die Handshake-Logik, die im gleichen Taktzyklus auf PCI-Signale reagieren kann, während dem Rest der Schaltung solche kurzen Response-Zeiten verwehrt bleiben, weil er über Eingangsregister in den I/O-Blöcken an den PCI-Bus angekoppelt ist.
 
VHDL-Realisierung

Bild 7. VHDL-Realisierung von 'pipcon'.

Einige Gleichungen aus der 'pci_top'-Komponente, die Zustandsmaschine 'pipcon' und das Modul 'critpath' erzeugen alle für das PCI-Protokoll benötigten Steuersignale. Die gesamte Funktionalität in der Schaltung wird durch die Zustandsmaschine 'pipcon' (Bild 7) gesteuert. 'pipcon' sorgt für das Erhöhen des PCI-Burst- und des Audiozählers und veranlaßt den Datentransfer zum SRAM. 'pipcon' ist Teil einer in hohem Maße auf Pipelining basierenden Kontrollstruktur, die nicht während derselben Taktflanke auf PCI-Steuersignale reagieren kann, da die PCI-Signale nur über Register eingehen. 'critpath' stellt die korrekte Beendigung einer PCI-Transaktion sicher, indem sie TRDY und DEVSEL schneller abschaltet, als die Zustandsmaschine es könnte.

Die Komponente 'critpath'

Der Inhalt des 'critpath' ist so einfach, daß er sich in einer CLB unterbringen läßt, die vollständig ausgenutzt ist. 'critpath' beinhaltet Funktionsgeneratoren vor den mit Registern bestückten Ausgangsbuffern der PCI-Leitungen TRDY und DEVSEL. Die Haupteingänge zu diesen Funktionsgeneratoren sind die direkten PCI-Signale FRAME und IRDY.

Während das taktsynchrone Anschalten von TRDY und DEVSEL zu Beginn einer Transaktion keine Probleme bereitet, ist das Zurücknehmen der beiden Signale am Ende eines Bursttransfers besonders zeitkritisch. Um diesen Fall korrekt zu behandeln, müssen die PCI-Signale FRAME und IRDY direkt abgegriffen werden, den Funktionsgenerator einer CLB durchlaufen und vor dem Taktsignal bei den I/O-Registern von TRDY und DEVSEL eintreffen. In der CLB des 'critpath' steuern die PCI-Signale direkt die Freigabe der Ausgänge der Zustandsmaschine. Dies ist die einzige Stelle, in der die PCI-Steuersignale kombinatorisch verknüpft werden, ohne sie vorher über Input-Register zu führen. Die CLB wird in der Nähe der PADs, die die PCI-Signale FRAME, IRDY, TRDY, DEVSEL führen, von Hand durch Setzen von Attributen plaziert, um minimale Laufzeiten zu garantieren.

Die Komponente 'pipcon'

In dem Modul 'pipcon' (Bild 7) ist eine Zustandsmaschine mit acht Zuständen untergebracht, die den Datenfluß in der gesamten Schaltung (PCI- und Audio-Teil) steuert, indem sie sieben verschiedene Steuersignale erzeugt. Die VHDL-Beschreibung der Zustandsmaschine ist in Bild 8 wiedergegeben. Diese ist in einer Form modelliert, die als besonders synthesefreundlich gilt, denn sie enthält einen Prozeß ('state_register') für die Zustandsspeicherung und einen weiteren Prozeß ('state_logic') für den kombinatorischen Teil. Da die Beschreibung der Übergangslogik und der Ausgangslogik sehr ähnlich ist, kann sie in dem Prozeß 'state_logic' zusammengefaßt werden.

Das Ausgangssignal y (1 to 7) wird kombinatorisch aus dem Zustandsregister und den Eingangssignalen gebildet. Im Idle-Zustand finden weder PCI- noch Audio-Aktivitäten statt. Ausgehend vom Idle-Zustand können drei Schleifen durchlaufen werden. Die Audiokomponente kennt keinen Unterschied zwischen Aufnahme und Wiedergabe. Es werden grundsätzlich Daten in beide Richtungen übertragen. Vom Idle-Zustand kann die Zustandsmaschine in den Read-Zustand wechseln, um ein 32-Bit-Wort mit Musikdaten aus dem Speicher zu lesen und in einem Eingangsdatenregister, das sich vor dem Schieberegister befindet, abzulegen. Der folgende Write-Zustand veranlaßt, daß das Datenwort aus dem Ausgangsregister, das an den parallelen Ausgangsleitungen des Schieberegisters hängt, ins SRAM transferiert wird. Für den seriellen Audio-Ein- und Ausgang kann man dasselbe Schieberegister verwenden.

Die beiden anderen Schleifen der Ablaufsteuerung sind für Read-Burst und Write-Burst Zugriffe verantwortlich. Das Prinzip von Lese- und Schreiboperation ist ähnlich, und wird deshalb hier nicht getrennt betrachtet. Mit Hilfe des WRrd-Signals, das aus dem Kommando-Code abgeleitet wird, kann ein Lese- und Schreibzugriff unterschieden werden. Die Schleifen werden durchlaufen, wenn gleichzeitig das PCI_REQ- und PCI_GNT-Signal anliegen. PCI_GNT zeigt, daß der Speicher exklusiv dem PCI-Bus zur Verfügung steht und nicht der Audio-Komponente. Die Zwischenzustände gehen bedingungslos in die Zustände RdBurst beziehungswei- se WrdBurst über, die erst wieder verlassen werden, wenn das PCI_REQ-Signal zurückgenommen wird. Die Zwischenzustände sind notwendig, um die Daten-Pipeline zu laden und die nötigen Steuersignale zu erzeugen.

Der Ausgangsvektor y der Zustandsmaschine geht in die Steuersignale TRDY_SM, WRGATE, SROE_INTn, SRD_T, INC_ADDR, load und ack über: TRDY_SM sorgt dafür, daß das eigentliche PCI-Signal TRDY im nächsten Taktzyklus erzeugt wird. Das TRDY-Signal bleibt bis nach Beenden des letzten Datentransfers auf dem PCI-Bus gesetzt. WRGATE zeigt an, daß im nächsten Taktzyklus ein Schreibzugriff auf das SRAM stattfinden soll. Zusätzlich muß noch gelten, daß die PCI-Leitungen C/BE, die während der Datenphase die Bedeutung von Byte-Enable-Leitungen haben, auf Low liegen und keine Initiatorwartezyklen stattfinden. Das SROE_INTn-Signal ist über ein nachgeschaltetes I/O-Flipflop direkt mit der OE-Leitung des SRAMs verbunden.

Der y-Vektor wurde für den Prozeß 'state_logic' eingeführt, um mit einer VHDL-Anweisung allen Ausgängen einen Wert zuweisen zu können. Die Elemente 1... 3 des y-Ausgangsvektors werden direkt den Signalen TRDY_SM, WRGATE, SROE_INTn zugeordnet, um dem y-Vektor eine anschauliche Bedeutung zu geben. Die Komponenten des y-Vektors 4-7 laufen über Ausgangs-Flipflops zu den Signalen SRD_T, INC_ADDR, load und ack.

Das SRD_T Signal schaltet die 3-State-Ausgangsbuffer des FPGA frei, die zu den Datenleitungen der SRAM führen. SRD_T ist das Gegenstück zum SROEn-Signal. Beim Umschalten der Datenflußrichtung der SRAMs sind für einen Taktzyklus beide Steuerleitungen inaktiv, um kurzzeitige Kurzschlüsse auszuschließen. Das INC_ADDR-Signal bewirkt das Hochzählen der Adresse während eines Burstzugriffes; andernfalls kann entweder eine Audio-Adresse oder eine PCI-Startadresse, die in der Adreßphase der PCI-Master mitteilt, geladen werden. Das Ack-Signal quittiert eine Datenanforderung der Audiokomponente, die über LOC_REQ eingeleitet wird. Außerdem bewirkt es noch, daß die Audioadresse inkrementiert wird. Das Load-Signal schließlich versorgt das Audio-Datenregister reg_2 mit frischen Daten.

SRAM-Timing

Um optimale Datenflußraten zu erreichen, muß der 32 Bit breite SRAM-Speicher in der Lage sein, mit jedem PCI-Taktzyklus ein Datenwort zu verarbeiten. Dazu sind SRAMs mit Zugriffszeiten von 15 ns oder schneller erforderlich. Das Lese-Timing ist relativ einfach einzuhalten: Gültige Daten liegen wenig später nach Änderung der Adressen an. In einem ersten Taktzyklus wird dem SRAM eine Adresse mitgeteilt. Mit der steigenden Flanke des nächsten Taktes übernimmt das FPGA die Daten.
 
Schaltplan

Bild 9. Der Hauptteil der Schaltung steckt im FPGA von Xilinx.

Das Schreib-Timing ist aufwendiger zu erzeugen und erfordert besondere Überlegungen. Ein vollkommen synchrones Design ist nur mit einem 66-MHz-Takt realisierbar, denn es werden Schreibimpulse von 15 ns Länge benötigt. Ein solcher Takt steht jedoch nicht zur Verfügung. Es wurden deshalb andere Wege gegangen: Alle Daten- und Adreßsignale legt das FPGA weiterhin synchron zum Takt an. Nur das CS-Signal der SRAMs wird asynchron gebildet, indem man ein Schreibsignal mit dem Takt verknüpft. Durch Routing-Verzögerungen im FPGA wird der CS-Impuls um die Länge einer halben Taktperiode in die Mitte eines Taktzyklus verschoben. Wenn die Verzögerung kleiner als 15 ns ist, ist der CS-Impuls vor der frühestmöglichen Änderung der Adresse wieder inaktiv.

Initiator-Wartezyklen

Die Behandlung von Initiator-Wartezyklen bei Schreibzugriffen ist einfach. Zusammen mit den Daten wird der jeweilige Zustand von IRDY durch die Pipeline geschickt. Falls der Initiator nicht bereit ist, wird der SRAM-Schreibpuls und das Inkrementieren der Adresse ausgesetzt. Initiator-Wartezyklen beim Lesen unterbrechen die Pipeline, da immer zwei Datenworte im voraus gelesen werden, um den Datenfluß mit maximaler Geschwindigkeit ohne das Einlegen von Wartezyklen aufrecht zu erhalten. Daher hat der Adreßzähler schon für einige Taktzyklen weitergezählt, bevor er angehalten werden kann.

Dieser Fall stellt für unser Design kein Problem dar, denn die im voraus gelesenen Datenworte gehen nicht verloren, sondern stehen weiterhin in der Pipeline. Aufwendiges Neufüllen der Pipeline kann entfallen, falls der aktuelle Zustand der Pipeline während eines Wartezyklus eingefroren werden kann. Dies ist dank der Taktfreigabeleitung der I/O-Flipflops möglich.

Die Verzögerung zum Freischalten der Tri-State-Ausgänge des XC4000E sind wesentlich größer als der 'Clock-to-Output'-Parameter. In diesem Design wird das Aktivieren der Ausgänge einen Taktzyklus früher eingeleitet, um mit der 'Float-to-Activ'-Verzögerung innerhalb der PCI-Spezifikation zu bleiben. Zum Deaktivieren der Ausgänge sieht die PCI-Spezifikation glücklicherweise einen ganzen Taktzyklus minus 2 ns vor.

Neben I/O- und Speicherzugriffen auf dem PCI-Bus, die den üblichen I/O- und Speicherzugriffen bei Intel-Prozessoren entspricht, gibt es einen besonderen PCI-Konfigurationsmechanismus.

Die Komponente 'cfgblock'

Der Konfigurationsbereich einer PCI-Karte besitzt einige Register zur Identifikation der Hardware und zum Festlegen der benutzten Systemressourcen (I/O-Adressen, Speicheradressen und Interrupts). Damit ist eine PCI-Karte voll softwarekonfigurierbar.

Der Konfigurationsbereich teilt sich auf in einen vordefinierten Header (64 Byte) und einen Teil, der geräteabhängig ist (192 Bytes). Es müssen nicht alle 256 Register implementiert werden. Beim Lesen nicht vorhandener Register muß Null zurückgegeben werden. Bei dieser Audiokarte ist der PCI-Konfigurationsbereich im FPGA untergebracht. Die Komponente 'cfgblock' ist sowohl für die Implementierung des PCI-Konfigurationsbereiches als auch eines Steuerregisters zuständig, das die gesamte Audiokarte kontrolliert.

Plug & Play ist unverzichtbar

Die unverzichtbaren Register des Konfigurationsbereiches sind Device-ID, Vendor-ID, Status, Command, Class-Code und Revision-ID. Die Vendor-ID ist eine 16-Bit-Konstante, die die beiden Autoren als Kartenhersteller ausweist. Falls sich jemand darüber beschwert, daß er die gleiche ID gegen eine Gebühr von 2500 US-$ pro Jahr bei der PCI SIG reserviert hat, wollen die Autoren die Konstante gern um 1 erhöhen...
 
Platine

Bild 10. Die Platine ist trotz der Komplexität nur zweilagig.

Bit 9 und 10 im Statusregister geben binär '10' zurück und signalisieren damit ein langsames (slow) DEVSEL-Timing. Bit 1 im Command-Register liegt auf 1, um anzuzeigen, daß das PCI-Gerät auf Speicherzugriffe reagiert. Interrupt-Betrieb wird mit Hilfe des Interrupt-Line/Interrupt-Pin-Register bewerkstelligt. Das Interrupt-Pin-Register teilt mit, daß der benötigte Interrupt über die PCI-Leitung INT A läuft. Das Interrupt-Line-Register nimmt die PC-IRQ-Nummer auf und hat für die Schaltung keine weitere Bedeutung. Die Karte belegt einen 16 MBytw großen Adreßbereich. Das Basisadreßregister der Schaltung akzeptiert Schreibzugriffe nur in den obersten 8 Bits. Die unteren Bits geben bei einem Lesezugriff immer Null zurück.

Adreßbereich

Die untersten vier Bit sind von dieser Regel ausgenommen, sie haben eine besondere Bedeutung: Bei Leseoperationen wird das Bitmuster '1000' zurückgegeben, das heißt, der Speicher ist prefetchable, und es ist möglich, ihn irgendwo im 32-Bit-Raum zu plazieren. roe
Hinweis: wird fortgesetzt