Audio-DSP mit Spartan 3-FPGA: Unterschied zwischen den Versionen

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche
 
(17 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt)
Zeile 3: Zeile 3:
==Ziel==
==Ziel==


Ziel dieses Projekts ist es, eine FPGA-basierte Plattform aufzubauen mit der es möglich ist Synthesizer, Effektgeräte, Mischpulte oder gar ein Harddiskrecording-System zu realisieren.
Ziel dieses Projekts ist es der Aufbau einer FPGA-basierten Plattform, mit der es möglich ist Synthesizer, Effektgeräte, Mischpulte oder gar ein Harddiskrecording-System zu realisieren.


==Feature-Liste==
==Feature-Liste==


Features des Audio-Prozessors:  
Eigenschaften des Audioprozessors:  


* Oszillatoren
* Oszillatoren
Zeile 13: Zeile 13:
* Addierer, Schalter, Verstärker (Multiplizierer)
* Addierer, Schalter, Verstärker (Multiplizierer)
* Delays
* Delays
* Steuerung des Audio-Prozessors via SPI oder RS232
* Steuerung des Audioprozessors via SPI oder RS232
* 4 Mono Ein- und Ausgänge
* 4 Mono Ein- und Ausgänge
* GPO (General Purpose Outputs) zur Konfiguration der Codecs
* GPO (General-Purpose-Outputs) zur Konfiguration der Codecs


==Übersicht==
==Übersicht==
[[Bild:Overview_wo_uc.jpg|thumb|500px]]
[[Bild:Overview_wo_uc.jpg|thumb|500px]]
Basis des Audio-Systems ist das Xilinx Spartan 3-Development Board. An diesem Board werden 2 Audio-Codecs angschlossen von denen einer als Master und der andere als Slave agiert. Optional kann noch ein Mikrocontroller angeschlossen werden welcher den FPGA per SPI steuert. Da dieses Projekt mittlerweile recht umfangreich geworden ist, kann ich hier nur einen kurzen Umriss des Systems geben. Dabei beschränke ich mich auf die grobe Funktionsweise des Audio-Prozessors, erläutere das Interface (welches ich als Basis für weitere Projekte bereits nutze) und gebe einen kleinen Überblick über die Hardware.
Basis des Audiosystems ist das Spartan-3-Development-Board von Xilinx. An diesem Board werden zwei Audio-Codecs angeschlossen, von denen einer als Master und der andere als Slave agiert. Optional kann noch ein Mikrocontroller angeschlossen werden, welcher den FPGA per SPI steuert. Da dieses Projekt mittlerweile recht umfangreich geworden ist, kann ich hier nur einen kurzen Umriss des Systems geben. Dabei beschränke ich mich auf die grobe Funktionsweise des Audioprozessors, erläutere die Schnittstelle (welche ich als Basis für weitere Projekte bereits nutze) und gebe einen kleinen Überblick über die Hardware.


Das System kann (sofern man 2 Audio-Codecs, von denen einer als Master, der andere als Slave arbeitet, angeschlossen und konfiguriert hat) direkt genutzt werden, da der DAP per RS232 gesteuert werden kann. Der Audio-Prozessor startet mit einem Stereo-Tiefpass-Filter der sich auf den ersten Codec bezieht,
Das System kann (sofern man zwei Audio-Codecs, von denen einer als Master, der andere als Slave arbeitet, angeschlossen und konfiguriert hat) direkt genutzt werden, da der DAP per RS232 gesteuert werden kann. Der Audioprozessor startet mit einem Stereo-Tiefpassfilter, das sich auf den ersten Codec bezieht,
sodass man ein erstes Demo hat (selbst wenn es etwas unspektakulär ist)
sodass man eine erste Demo hat (selbst wenn diese etwas unspektakulär ist)


<br clear="all" />
<br clear="all" />
Zeile 28: Zeile 28:
==Nachbau==
==Nachbau==


Derjenige der sich dieses System nachbauen möchte benötigt erstmal ein FPGA-Board. Mit dem Spartan 3 Board von Digilent gestaltet sich der Nachbau einfach, weil die Programmier-Dateien für den FPGA direkt für dieses Board verwendet werden können. Nutzer anderer Boards (Xilinx) müssten zuerst die UCF-Datei für die Pins ihres jeweiligen Boards anpassen, und dieses Projekt neu synthetisieren (compilieren). Nutzer von Altera-Boards hingegen müssen die BlockRAM Instanzen auf die Altera-Architektur anpassen (den Inhalt der RAMs dabei nicht vergessen :-). Vielleicht findet sich ja der eine oder andere der den VHDL Code für Altera-FPGAs portiert.
Wer sich dieses System nachbauen möchte, benötigt zunächst ein FPGA-Board. Mit dem Spartan-3-Board von Digilent gestaltet sich der Nachbau einfach, weil die Programmier-Dateien für den FPGA direkt für dieses Board verwendet werden können. Nutzer anderer Boards (Xilinx) müssten zuerst die UCF-Datei für die Pins ihres jeweiligen Boards anpassen, und dieses Projekt neu synthetisieren (compilieren). Nutzer von Altera-Boards hingegen müssen die BlockRAM-Instanzen auf die Altera-Architektur anpassen (den Inhalt der RAMs dabei nicht vergessen :-). Vielleicht findet sich ja der eine oder andere der den VHDL Code für Altera-FPGAs portiert.
Der eigentliche wichtige Teil eines Nachbaus ist der Codec-Teil. Dieses System verwendet zwar zwei Codecs, aber es kann auch mit einem gearbeitet werden. Als Codec kommt der TLV320AIC23B von Texas Instruments zum einsatz. Diesen kann man als kostenloses Sample bei TI direkt bekommen.  
Der eigentliche wichtige Teil eines Nachbaus ist der Codec-Teil. Dieses System verwendet zwar zwei Codecs, aber es kann auch mit einem gearbeitet werden. Als Codec kommt der TLV320AIC23B von Texas Instruments zum Einsatz. Diesen kann man als kostenloses Muster bei TI direkt bekommen.  
Des weiteren benötigt man noch eine handvoll Bauteile wie Kondensatoren, Widerstände und einen Quarz. (Ein Codec MUß als Master laufen, sonst hat das System keine Audio-Clocks, da diese nicht vom FPGA generiert werden)
Des weiteren benötigt man noch eine handvoll Bauteile wie Kondensatoren, Widerstände und einen Quarz. (Ein Codec MUSS als Master laufen, sonst hat das System keine Audio-Clocks, da diese nicht vom FPGA generiert werden)
Die Initialisierung des Codecs wird vom PC aus gemacht. Dazu dienen die 4 GPO Leitungen auf dem B1- Connector. Da der Codec nur "halbes" SPI unterstüzt (man kann nur schreiben, nicht lesen) gestaltet sich die Initialisierung recht einfach.
Die Initialisierung des Codecs wird vom PC aus gemacht. Dazu dienen die 4 GPO-Leitungen auf dem B1-Verbinder. Da der Codec nur "halbes" SPI unterstüzt (man kann nur schreiben, nicht lesen) gestaltet sich die Initialisierung recht einfach.
Die 4 GPO-Leitungen teilen sich folgendermaßen auf :
Die 4 GPO-Leitungen teilen sich folgendermaßen auf :


Zeile 43: Zeile 43:
[[bild:Overview dap core.JPG|thumb|500px|right]]
[[bild:Overview dap core.JPG|thumb|500px|right]]


Der FPGA beinhaltet in dem gesamten System einen Quasi-DSP. Quasi-DSP deshalb, da die Struktur im Gegensatz zu einem DSP bzw. Mikrocontroller keine Verzweigungen, Interrupts oder ähnliches zulässt. Der Audio-Prozessor besteht im wesentlichen aus 3 Teilen : Einem Rahmen, einem SDSP (Small DSP)-Kern  
Der FPGA beinhaltet in dem gesamten System einen Quasi-DSP. Quasi-DSP deshalb, da die Struktur im Gegensatz zu einem DSP bzw. Mikrocontroller keine Verzweigungen, Interrupts oder ähnliches zulässt. Der Audio-Prozessor besteht im wesentlichen aus 3 Teilen : einem Rahmen, einem SDSP (Small DSP)-Kern  
sowie einem Utility-Kern. Beide Kerne können theoretisch parallel arbeiten, da jeder Kern eine eigene Statemachine und einen eigenen Mikro-Code Speicher besitzen. Dieses Feature ist allerdings noch nicht implementiert.
sowie einem Utility-Kern. Beide Kerne können theoretisch parallel arbeiten, da jeder Kern einen eigenen Zustandsautomaten und einen eigenen Microcode-Speicher besitzen. Diese Möglichkeit ist allerdings noch nicht implementiert.


Der SDSP-Kern besteht im wesentlichen aus einer MAC-Einheit, einem Speicher für Audio-Daten, einem Koeffizienten-Speicher, einem Adress-Generator und mehreren Muxern, sowie der schon angesprochenen Statemachine und dem Microcode. Weiterhin ist ein Hidden-Write- (bzw. Shadow Register) Mechanismus integriert,
Der SDSP-Kern besteht im wesentlichen aus einer MAC-Einheit, einem Speicher für Audiodaten, einem Koeffizienten-Speicher, einem Adressgenerator und mehreren Muxern, sowie dem schon angesprochenen Zustandsautomaten und dem Microcode. Weiterhin ist ein Hidden-Write- (bzw. Shadow Register) Mechanismus integriert,
welcher ein "knackser-freies" Updaten von Koeffizienten ermöglicht. Alle diese Komponenten werden vom MicroCode aus gesteuert (genau wie bei einem Mikrocontroller). Mit diesem Kern ist es möglich, Audio-Signale zu bearbeiten. Zu Den Bearbeitungsmöglichkeiten zählen in erster Linie das Verändern der Lautstärke, Mischen, Filtern (Biquad) sowie Laden und Speichern von  
welcher ein "knackserfreies" Aktualisieren von Koeffizienten ermöglicht. Alle diese Komponenten werden vom Microcode aus gesteuert (genau wie bei einem Mikrocontroller). Mit diesem Kern ist es möglich, Audiosignale zu bearbeiten. Zu Den Bearbeitungsmöglichkeiten zählen in erster Linie das Verändern der Lautstärke, Mischen, Filtern (Biquad) sowie Laden und Speichern von  
Audio-Werten.
Audiowerten.


Der Utility Kern besteht aus einem Akkumulator (für DDS), einem Shaper, einem Adress-Generator, einem Wavetable-Speicher, einem Random-Number Generator, einigen Muxern, (einem Adress-Generator für SRAM, einem SRAM-Controller; diese sind allerdings nur nutzbar wenn man das ganze mit dem ISE 6.2 synthetisiert)  
Der Utility-Kern besteht aus einem Akkumulator (für DDS), einem Shaper, einem Adressgenerator, einem Wavetable-Speicher, einem Zufallszahlengenerator, einigen Muxern, (einem Adressgenerator für SRAM, einem SRAM-Controller; diese sind allerdings nur nutzbar, wenn man das ganze mit dem ISE 6.2 synthetisiert)  
und der schon angesprochenen Statemachine und dem MicroCode. Der MicroCode steuert (genau wie beim SDSP-Kern) dabei die einzelnen Komponenten des Utility Kerns. Dieser kern ist für das Erzeugen von Audio-Signalen zuständig, und erlaubt ein Audio-Signal zu verzögern, sofern man die ISE-Version 6.2 Verwendet (später dazu mehr). Als Wellenformen stehen Sägezahn, Rechteck (mit veränderbarem Puls/Pausen-Verhältnis), Rauschen sowie benutzderdefinierbare Wellenformen (Wavetable) zur verfügung.
und dem schon angesprochenen Zustandsautomaten und dem Microcode. Der Microcode steuert (genau wie beim SDSP-Kern) dabei die einzelnen Komponenten des Utility-Kerns. Dieser Kern ist für das Erzeugen von Audiosignalen zuständig, und erlaubt ein Audiosignal zu verzögern, sofern man die ISE-Version 6.2 verwendet (später dazu mehr). Als Wellenformen stehen Sägezahn, Rechteck (mit veränderbarer Pulsbreite), Rauschen sowie benutzderdefinierbare Wellenformen (Wavetable) zur Verfügung.


Der Rahmen besteht aus einer Statemachine, einem Programm-Speicher, einigen Muxern, sowie einem doppelten I2S Sender-Empfänger (für 2 Stereo Ein- und Ausgänge). In dem Rahmen werden die beiden Kerne "eingehängt". Die Kerne werden vom Programmspeicher aus mit Daten versorgt, und von der Statemachine angetriggert. Der Programmspeicher (PMEM) ist als 512x32 Bit organisiert. Das heißt das ein Befehl im Programmspeicher 32 Bit Informationen enthält und der  
Der Rahmen besteht aus einem Zustandsautomaten, einem Programmspeicher, einigen Muxern, sowie einem doppelten I2S-Sender/Empfänger (für 2 Stereo Ein- und Ausgänge). In den Rahmen werden die beiden Kerne "eingehängt". Die Kerne werden vom Programmspeicher aus mit Daten versorgt, und vom Zustandsautomaten angesteuert. Der Programmspeicher (PMEM) ist als 512x32 Bit organisiert. Das heißt, dass ein Befehl im Programmspeicher 32 Bit an Informationen enthält und der Audioprozessor max. 512 Befehle umfassen kann.
Audio-Prozessor max. 512 Befehle umfassen kann.


===SDSP-Core===
===SDSP-Core===
Zeile 60: Zeile 59:
[[Bild:SDSP-Struct.jpg|thumb|300px|left|Struktur des SDSP-Kerns]]
[[Bild:SDSP-Struct.jpg|thumb|300px|left|Struktur des SDSP-Kerns]]


Der eigentliche Kern des DAPs ist die MAC-Einheit. Mit ihr werden die grundlegenden Operationen Multiplikation und Addition durchgeführt. Es ist eine 32x32 Bit Einheit.  
Der eigentliche Kern des DAPs ist die MAC-Einheit. Mit ihr werden die grundlegenden Operationen Multiplikation und Addition durchgeführt. Es ist eine 32x32-Bit-Einheit.  
Die Funktionsweise des Kerns ist eigentlich recht einfach.  
Die Funktionsweise des Kerns ist eigentlich recht einfach.  
Die MAC-Einheit hat 2 Eingänge. Einer dieser Eingänge kann ein Audio-Signal, ein Wert aus dem Audio-Speicher (AMEM-BlockRAM) oder ein zuvor berechnetes Ergebnis sein. Der andere Eingang kann ein Koeffizient aus dem CMEM-BlockRAM oder eine Konstante (1.000, 0.000 oder -1.000) sein.
Die MAC-Einheit hat 2 Eingänge. Einer dieser Eingänge kann ein Audiosignal, ein Wert aus dem Audiospeicher (AMEM-BlockRAM) oder ein zuvor berechnetes Ergebnis sein. Der andere Eingang kann ein Koeffizient aus dem CMEM-BlockRAM oder eine Konstante (1.000, 0.000 oder -1.000) sein.
Der Ausgang (32-Bit, hardgeclippt) geht auf das AMEM-BlockRAM und zum Ausgangs-Clipping. Das Ausgangsclipping schneidet das Audio-Signal auf 24-Bit zurecht.
Der Ausgang (32-Bit, hart geclippt) geht auf das AMEM-BlockRAM und zum Ausgangs-Clipping. Das Ausgangsclipping schneidet das Audiosignal auf 24-Bit zurecht.
Die Adressen für die Speicher (AMEM und CMEM) werden im Address-Generator erzeugt. Dieser wird von außen mit einer 8-bit Basis-Adresse gespeist und erzeugt einen Offset zu den Eingangs Adressen. Er besitzt 2 setzbare Zähler und einige Multiplexer.
Die Adressen für die Speicher (AMEM und CMEM) werden im Addressgenerator erzeugt. Dieser wird von außen mit einer 8-Bit-Basis-Adresse gespeist und erzeugt einen Offset zu den Eingangsadressen. Er besitzt 2 setzbare Zähler und einige Multiplexer.
Alle Steuerignale der Komponenten von einem weiteren aus BlockRAM (MMEM) versorgt. Weiterhin wird von außen eine Start-Adresse vorgegeben. Dadurch lassen sich quasi Opcodes mit von außen vorgegeben Parametern (Adressen) aufrufen.
Alle Steuersignale der Komponenten von einem weiteren aus BlockRAM (MMEM) versorgt. Weiterhin wird von außen eine Startadresse vorgegeben. Dadurch lassen sich quasi Opcodes mit von außen vorgegeben Parametern (Adressen) aufrufen.
Das MMEM-BlockRAM wird nun einfach nur linear ausgelesen bis ein Stop-Bit gesetzt ist.  
Das MMEM-BlockRAM wird nun einfach nur linear ausgelesen bis ein Stopbit gesetzt ist.


<br clear="all" />
<br clear="all" />
Zeile 87: Zeile 86:
* 1 Bit = Core Select (SDSP oder Utility)
* 1 Bit = Core Select (SDSP oder Utility)
* 1 Bit = Ende des Programms
* 1 Bit = Ende des Programms
* 4 Bit = Eingangs-Routing (Kanal 1 - 4, Ergebnis SDSP Core, Ergebnis Utility Core)
* 4 Bit = Eingangsrouting (Kanal 1 - 4, Ergebnis SDSP-Kern, Ergebnis Utility-Kern)
* 4 Bit = Ausgangs-Routing (SDSP-Ausgang auf Kanal 1-4, Utility Ausgang auf Kanal 1-4)
* 4 Bit = Ausgangsrouting (SDSP-Ausgang auf Kanal 1-4, Utility-Ausgang auf Kanal 1-4)
* 8 Bit = Adresse 1 (bei SDSP für Audio-Memory, bei Utility Kern für Data Memory)
* 8 Bit = Adresse 1 (bei SDSP für Audio-Memory, bei Utility-Kern für Datenspeicher)
* 8 Bit = Adresse 2 (bei SDSP für Koeffizienten-Memory, bei Utility Kern unbenutzt)
* 8 Bit = Adresse 2 (bei SDSP für Koeffizientenspeicher, bei Utility-Kern unbenutzt)


Das Eingangsrouting bestimmt mit welchem Signal der gewählte Kern arbeiten soll. Dies können die Eingänge 1-4 sein, aber auch ein vorher berechnetes Ergebnis des SDSP- bzw. Utility-Kerns sein. Das Ausgangsrouting bestimmt von welchem Kern das Signal auf welchen Ausgang geroutet wird.
Das Eingangsrouting bestimmt, mit welchem Signal der gewählte Kern arbeiten soll. Dies können die Eingänge 1-4 aber auch ein vorher berechnetes Ergebnis des SDSP- bzw. Utility-Kerns sein. Das Ausgangsrouting bestimmt, von welchem Kern das Signal auf welchen Ausgang geroutet wird.


Die Opcodes des DAPs sind:
Die Opcodes des DAPs sind:
Zeile 98: Zeile 97:
SDSP-Kern:
SDSP-Kern:
* Biquad rechnen
* Biquad rechnen
* Audio Wert speichern
* Audiowert speichern
* Audio Wert laden
* Audiowert laden
* Move eines Wertes im Audio-Speicher
* Move eines Wertes im Audiospeicher
* Summe resetten
* Summe rücksetzen
* Eingang zu Summe addieren
* Eingang zu Summe addieren
* Wert aus dem Audio-Speicher zu Summe addieren
* Wert aus dem Audiospeicher zu Summe addieren
* Eingang zu summe mischen (mit Lautstärke Koeffizient)
* Eingang zu Summe mischen (mit Lautstärkekoeffizient)
* wert aus dem Audio-Speicher zu Summe mischen (mit Lautstärke Koeffizient)
* Wert aus dem Audiospeicher zu Summe mischen (mit Lautstärkekoeffizient)
* Lautstärke  
* Lautstärke  


Zeile 111: Zeile 110:
* Oszillator (DDS-Teil)
* Oszillator (DDS-Teil)
* Waveshaper
* Waveshaper
* Delay
* Verzögerung


Der Ablauf eines Audio-Programms ist folgender:
Der Ablauf eines Audio-Programms ist folgender:


Sobald ein neues Sample anliegt, wird die Abarbeitung des Programms von Adresse 0x0000 an im PMEM angestossen. Es wird dabei jeweils ein Befehl geladen und Daten wie Opcode und Adressen liegen dabei an beide Kernen gleichermaßen an. Ist das Programm-Ende Bit nicht gesetzt so wird der jeweilige Kern (mit dem im Opcode angegeben Routing) angetriggert. Legt der betreffende Kern sein Ready Signal auf 1, so wird der nächste Befehl abgearbeitet. Dieses Verhalten (Laden und Verteilen von Opcode-Daten, sowie die Ablaufsteuerung; also das Antriggern des Programms, Antriggern der einzelnen Kerne, warten auf dessen Abarbeitung und das Programm-Ende) wird vom Rahmen übernommen.
Sobald ein neues Sample anliegt, wird die Abarbeitung des Programms von Adresse 0x0000 an im PMEM angestoßen. Es wird dabei jeweils ein Befehl geladen und Daten wie Opcode und Adressen liegen dabei an beide Kernen gleichermaßen an. Ist das Programm-Ende-Bit nicht gesetzt, so wird der jeweilige Kern (mit dem im Opcode angegeben Routing) angesteuert. Legt der betreffende Kern sein Ready-Signal auf 1, so wird der nächste Befehl abgearbeitet. Dieses Verhalten (Laden und Verteilen von Opcode-Daten sowie die Ablaufsteuerung, also das Ansteuern des Programms, Ansteuern der einzelnen Kerne, warten auf dessen Abarbeitung und das Programmende) wird vom Rahmen übernommen.


===Speicherorganisation===
===Speicherorganisation===


Alle Speicher die vom DAP angesprochen werden haben eine Wort-Breite von 32 Bit, der Zugriff erfolgt aber ausschließlich über 8 Bit Breite (Interface).
Alle Speicher die vom DAP angesprochen werden, haben eine Wortbreite von 32 Bit, der Zugriff erfolgt aber ausschließlich über eine Breite von 8 Bit (Interface).


DAP
DAP
Zeile 125: Zeile 124:


SDSP
SDSP
* Audio-Speicher   (AMEM)  von außen nicht zugänglich
* Audiospeicher   (AMEM)  von außen nicht zugänglich
* Koeffizienten-Speicher (CMEM)  0x2000 - 0x2023  (man "sieht" nur den Hidden Write -> später mehr dazu)
* Koeffizientenspeicher (CMEM)  0x2000 - 0x2023  (man "sieht" nur den Hidden Write -> später mehr dazu)
* Microcode-Speicher     (MMEM)  0x4000 - 0x47ff
* Microcodespeicher     (MMEM)  0x4000 - 0x47ff


Utility-Core
Utility-Core
* Daten-Speicher         (DMEM)  0x6000 - 0x67ff
* Datenspeicher         (DMEM)  0x6000 - 0x67ff
* Wavetable Speicher      (WMEM)  0x8000 - 0x87ff
* Wavetable-Speicher      (WMEM)  0x8000 - 0x87ff
* MicroCode-Speicher     (UMEM)  0xa000 - 0xa7ff
* Microcodespeicher     (UMEM)  0xa000 - 0xa7ff


===Hidden-Write===
===Hidden-Write===
Um bei Änderung der Koeffizienten "Knackser" zu vermeiden (die dadurch entstehen das der Koeffizient nur teilweise [durch 8 Bit Zugriffe] geändert wird, währenddessen aber Audio trotzdem noch "weiterläuft", und mit "falschen" Zwischenwerte gerechnet wird) ist ein Mechanismus implementiert der die zu ändernden Koeffizienten im Hintergund in den Speicher schreibt. Um diesen Mechanismus zu nutzen müssen zuerst die Koeffizienten in interne Register
Um bei Änderung der Koeffizienten Knackser zu vermeiden (die dadurch entstehen, dass der Koeffizient nur teilweise [durch 8-Bit-Zugriffe] geändert wird, währenddessen aber Audio trotzdem noch "weiterläuft" und mit "falschen" Zwischenwerten gerechnet wird), ist ein Mechanismus implementiert, der die zu ändernden Koeffizienten im Hintergund in den Speicher schreibt. Um diesen Mechanismus zu nutzen, müssen zuerst die Koeffizienten in interne Register
geschrieben werden. Die Register (es sind 8 32 Bit Register) liegen im Speicherbereich 0x2000 bis 0x201f. Die Speicherstelle 0x2020 gibt die Start-Adresse innerhalb des Koeffizienten Speichers an. Diese Adresse ist nur 8 Bit breit. Die Speicherstelle 0x2021 gibt an wieviele der 8 Register übertragen werden sollen. Die Speicherstelle 0x2022 triggert den Kopier-Vorgang an. Hier reicht es ein Dummy byte zu schreiben. Um den Kopiervorgang zu beenden (MUß GEMACHT WERDEN!!, sonst können keine weiteren Koeffizienten Updates gemacht werden) schreibt man an Speicherstelle 0x2023 ebenfalls ein Dummy Byte.
geschrieben werden. Die Register (es sind 8 32-Bit-Register) liegen im Speicherbereich 0x2000 bis 0x201f. Die Speicherstelle 0x2020 gibt die Startadresse innerhalb des Koeffizientenspeichers an. Diese Adresse ist nur 8 Bit breit. Die Speicherstelle 0x2021 gibt an, wieviele der 8 Register übertragen werden sollen. Die Speicherstelle 0x2022 löst den Kopiervorgang aus. Hier reicht es, ein Dummy-Byte zu schreiben. Um den Kopiervorgang zu beenden (MUSS GEMACHT WERDEN, sonst können keine weiteren Koeffizientenupdates gemacht werden), schreibt man an Speicherstelle 0x2023 ebenfalls ein Dummy-Byte.


===I/O Register===
===I/O Register===


Es gibt noch einen 8-Bit breiten Adress-Bereich innerhalb des DAPs mit dem der I2S-Teil gemutet werden kann. Weiterhin hat man die Möglichkeit die Anzahl der System-Takte pro Sample und die Anzahl der aktiven System-Takte (also die Zeit die der Audio-Prozessor beschäftigt ist) zu ermitteln. Dadurch lässt sich eine Auslastungsanzeige des DAPs realisieren.
Es gibt noch einen 8-Bit breiten Adressbereich innerhalb des DAPs, mit dem der I2S-Teil stummgeschaltet werden kann. Weiterhin hat man die Möglichkeit, die Anzahl der Systemtakte pro Sample und die Anzahl der aktiven Systemtakte (also die Zeit die der Audioprozessor beschäftigt ist) zu ermitteln. Dadurch lässt sich eine Auslastungsanzeige des DAPs realisieren.
 
 


===Interface===
===Interface===


Um von außen nun ein Programm (bzw. Koeffizienten und Daten) zu laden ist ein Interface implementiert, welches einfach zu handhaben ist und einfach erweitert werden kann. Das Interface kann per RS232 (fest eingestellt auf 115,2kBaud) oder per SPI (wird Hardware-Mässig eingestellt) angesteuert werden. Das Interface in seiner Gesamtheit ist schichtweise aufgebaut und beginnt mit einem Data-Dispatcher. Dieser Data-Dispatcher entscheidet (nach dem dieser selektiert wurde) mit dem ersten Byte, an welches angeschlossene Gerät der weitere Datenstrom geleitet wird.
Um von außen nun ein Programm (bzw. Koeffizienten und Daten) zu laden, ist eine einfach zu handhabende und erweiterbare Schnittstelle implementiert. Die Schnittstelle kann per RS232 (fest eingestellt auf 115,2kBaud) oder per SPI (wird hardwaremäßig eingestellt) angesteuert werden. Die Schnittstelle in ihrer Gesamtheit ist schichtweise aufgebaut und beginnt mit einem Daten-Dispatcher. Dieser Daten-Dispatcher entscheidet (nachdem dieser selektiert wurde) mit dem ersten Byte, an welches angeschlossene Gerät der weitere Datenstrom geleitet wird.
 
Als angeschlossene Geräte sind im aktuellen Design ein Gerät namens "StdIO" und der Audio-Prozessor angeschlossen.


Das "StdIO" Gerät steuert die 7Segment-Anzeige (16-Bit Hexadezimal Anzeige oder 32-Bit Einzelsegment Anzeige), die 8 Leuchtdioden, und erlaubt es die 3 Drucktaster sowie die 8 Schiebeschalter auszulesen.
Als angeschlossene Geräte sind im aktuellen Entwurf ein Gerät namens "StdIO" und der Audioprozessor verfügbar.


Der Audio-Prozessor besteht (Interface-seitig gesehen) nur aus einem Speicher-Zugriffs-Interface. Dieses Speicher-Interface entscheidet mit dem ersten Byte (sobald es selektiert wurde) ob in den Speicher geschrieben, von diesem gelesen, ein I/O Schreib oder Lese Zugriff erfolgen soll.
Das "StdIO"-Gerät steuert die 7-Segment-Anzeige (16-Bit-Hexadezimalanzeige oder 32-Bit-Einzelsegmentanzeige) sowie die 8 Leuchtdioden, und erlaubt es, die 3 Drucktaster sowie die 8 Schiebeschalter auszulesen.
Die Folgenden 2 Bytes (im Falle eines I/O Zugriffs nur 1 Byte) bestimmen die Adresse und damit den Speicher-Bereich des Audio-Prozessors auf den Zugegriffen werden soll. Das Speicherinterface besitzt einen Autoincrement,
mit dem fortalufende Bytes einfach hintereinander weggeschrieben werden können, ohne das jedesmal wieder der FPGA, das Gerät und die neue Adresse neu geschrieben werden müssen, was den Zugriff erheblich beschleunigt.


Der Audioprozessor besteht (schnittstellenseitig) nur aus einer Speicherzugriffsschnittstelle. Diese Schnittstelle entscheidet mit dem ersten Byte (sobald es selektiert wurde), ob in den Speicher geschrieben, von diesem gelesen, ein I/O-Schreib- oder -Lesezugriff erfolgen soll.
Die folgenden 2 Bytes (im Falle eines I/O-Zugriffs nur 1 Byte) bestimmen die Adresse und damit den Speicherbereich des Audioprozessors, auf den zugegriffen werden soll. Die Speicherschnittstelle besitzt einen Autoinkrementierer,
mit dem fortlaufende Bytes einfach hintereinander geschrieben werden können, ohne dass jedes mal wieder der FPGA, das Gerät und die neue Adresse neu geschrieben werden müssen, was den Zugriff erheblich beschleunigt.


Ursprünglich basierte das System auf einem SPI-Interface. Dabei wurde die Chip-Select Leitung als "globaler" Interface Reset betrachtet, d.h. war die Leitung auf High, war der FPGA Deselektiert und und alle Interface-Statemachines wurden im Reset gehalten. Erst mit dem Setzen dieser Leitung wurde der FPGA angesprochen. (erstes Byte -> Daten-Dispatcher, folgende Bytes gehen an das Gerät, wenn eines ausgewählt wurde). Weiterhin hat SPI die Eigenschaft das mit jedem gesendeten Byte auch eines Emfpangen wurde. Der Umstand das RS232 weder eine Chip-Select Leitung benötigt, noch eine synchrone Übertragung erzwingt führt zu dem Umstand das man bei Nutzung von RS232 einige Befehle zusätzlich benötigt. Diese Befehle werden durch das Zeichen 0x1b (ESC) eingeleitet. Soll statt der "Spezial-Funktion" das Byte 0x1b übertragen werden, so wird dieses einfach erneut gesendet. Soll die Chip-Select leitung gesetzt bzw. gelöscht werden so wird die Sequenz 0x1b 0x00 (Selektieren) bzw.
Ursprünglich basierte das System auf einem SPI-Interface. Dabei wurde die Chip-Select-Leitung als "globaler" Interface-Reset betrachtet, d.h. war die Leitung auf High, war der FPGA deselektiert und und alle Interface-Zustandsautomaten wurden im Reset gehalten. Erst mit dem Setzen dieser Leitung wurde der FPGA angesprochen. (erstes Byte -> Daten-Dispatcher, folgende Bytes gehen an das ausgewählte Gerät). Weiterhin hat SPI die Eigenschaft, dass mit jedem gesendeten Byte auch eines empfangen wurde. Der Umstand, dass RS232 weder eine Chip-Select Leitung benötigt noch eine synchrone Übertragung erzwingt, führt zu dem Umstand, dass man bei Nutzung von RS232 einige Befehle zusätzlich benötigt. Diese Befehle werden durch das Zeichen 0x1b (ESC) eingeleitet. Soll statt der "Spezialfunktion" das Byte 0x1b übertragen werden, so wird dieses einfach erneut gesendet. Soll die Chip-Select-Leitung gesetzt bzw. gelöscht werden, so wird die Sequenz 0x1b 0x00 (Selektieren) bzw.
0x1b 0x01 (Deselektieren) gesendet. Soll ein zuvor im Ausgangsregister gesetztes Byte gesendet werden so muß die Sequenz 0x1b 0x02 gesendet werden.
0x1b 0x01 (Deselektieren) gesendet. Soll ein zuvor im Ausgangsregister gesetztes Byte gesendet werden, so muss die Sequenz 0x1b 0x02 gesendet werden.


Beispiele:
Beispiele:


0x121b auf dem 7 Segment Display per RS232 Anzeigen:
0x121b auf dem 7-Segment-Display per RS232 anzeigen:


*- ESC 0x00  (FPGA Selektieren)
*- ESC 0x00  (FPGA selektieren)
*- 0xf0      (StdIO Selektieren)
*- 0xf0      (StdIO selektieren)
*- 0x00      (Hi Byte der 7 Segment Hex Anzeige wählen)
*- 0x00      (Hi-Byte der 7-Segment-Hex-Anzeige wählen)
*- 0x12      (Wert 12)
*- 0x12      (Wert 12)
*- ESC 0x01  (FPGA Deselektieren)
*- ESC 0x01  (FPGA deselektieren)


*- ESC 0x00  (FPGA Selektieren)
*- ESC 0x00  (FPGA selektieren)
*- 0xf0      (StdIO Selektieren)
*- 0xf0      (StdIO selektieren)
*- 0x01      (Lo Byte der 7 Segment Hex Anzeige wählen)
*- 0x01      (Lo-Byte der 7-Segment-Hex-Anzeige wählen)
*- 0x1b 0x1b (Wert 1b -> zu beachten: wenn der Wert 0x1b übertragen werden muß, muß dieser doppelt gesendet werden !!)
*- 0x1b 0x1b (Wert 1b -> zu beachten: wenn der Wert 0x1b übertragen werden soll, muss dieser doppelt gesendet werden !!)
*- ESC 0x01  (FPGA Deselektieren)
*- ESC 0x01  (FPGA deselektieren)


Beispiel um in den Programmspeicher des Audio-Prozessors an Adresse 0x0010 das Langwort 0x12233445 zu schreiben:
Beispiel, um in den Programmspeicher des Audioprozessors an Adresse 0x0010 das Langwort 0x12233445 zu schreiben:


*- ESC 0x00  (FPGA Selektieren)
*- ESC 0x00  (FPGA selektieren)
*- 0xf1      (DAP Selektieren)
*- 0xf1      (DAP selektieren)
*- 0x00      (Speicher Schreiben)
*- 0x00      (Speicher schreiben)
*- 0x00       
*- 0x00       
*- 0x10      (Adresse 0x0010 -> PMEM Adresse 0x010)
*- 0x10      (Adresse 0x0010 -> PMEM-Adresse 0x010)
*- 0x12     (Adresse 0x0010 -> 0x12)
*- 0x12     (Adresse 0x0010 -> 0x12)
*- 0x23     (Adresse 0x0011 -> 0x23, autoincrement)
*- 0x23     (Adresse 0x0011 -> 0x23, autoincrement)
*- 0x34      (Adresse 0x0012 -> 0x34, autoincrement)
*- 0x34      (Adresse 0x0012 -> 0x34, autoincrement)
*- 0x45      (Adresse 0x0013 -> 0x45, autoincrement)
*- 0x45      (Adresse 0x0013 -> 0x45, autoincrement)
*- ESC 0x01  (FPGA Deselektieren)
*- ESC 0x01  (FPGA deselektieren)


Auslesen der 8 Schalter:
Auslesen der 8 Schalter:


*- ESC 0x00  (FPGA Selektieren)
*- ESC 0x00  (FPGA selektieren)
*- 0xf0      (StdIO Selektieren)
*- 0xf0      (StdIO selektieren)
*- 0x04      (Schalter auslesen)
*- 0x04      (Schalter auslesen)
*- 0x00     (dummy byte -> überträgt Schalter-Stellung in Ausgabe-Register)
*- 0x00     (dummy byte -> überträgt Schalterstellung in Ausgaberegister)
*- ESC 0x02  (Ausgabe Register übertragen, danach empfängt man die 8 Schalterstellungen binär-codiert)
*- ESC 0x02  (Ausgaberegister übertragen, danach empfängt man die 8 Schalterstellungen binärcodiert)
*- ESC 0x01  (FPGA Deselektieren)
*- ESC 0x01  (FPGA deselektieren)


Der Datendispatcher (welcher mit dem ersten Byte nach dem Selektieren des FPGAs [0x1b 0x00] angesprochen wird) hat weiterhin einige nützliche Funktionen die in Ihrer Gesamtheit allerdings noch nicht ausführlich getestet wurden. Darunter sind Funktionen mit denen Inrformationen über die an den Ports des Daten-Dispatchers angeschlossenen Geräte zu ermitteln. Dieses Feature kann dazu genutuzt werden um zu ermitten welche Geräte im FPGA implementiert sind und an welchen Ports welche Geräte angeschlossen sind.
Der Datendispatcher (welcher mit dem ersten Byte nach dem Selektieren des FPGAs [0x1b 0x00] angesprochen wird) hat weiterhin einige nützliche Funktionen, die in ihrer Gesamtheit allerdings noch nicht ausführlich getestet wurden. Darunter sind Funktionen, mit denen Informationen über die an den Ports des Daten-Dispatchers angeschlossenen Geräte zu ermitteln. Diese Funktion kann dazu genutzt werden, um zu ermitten, welche Geräte im FPGA implementiert sind und an welchen Ports welche Geräte angeschlossen sind.


Anzahl der Ports des Daten Dispatchers liefern:
Anzahl der Ports des Daten-Dispatchers liefern:


*- ESC 0x00  (FPGA Selektieren)
*- ESC 0x00  (FPGA selektieren)
*- 0xed      (Anzahl Ports lesen)
*- 0xed      (Anzahl Ports lesen)
*- 0x00      (dummy byte -> überträgt Inhalt des Ausgabe-Registers)
*- 0x00      (dummy byte -> überträgt Inhalt des Ausgaberegisters)
*- ESC 0x02  (Ausgabe Register übertragen, danach empfängt man 0x22)
*- ESC 0x02  (Ausgaberegister übertragen, danach empfängt man 0x22)
*- ESC 0x01  (FPGA Deselektieren)
*- ESC 0x01  (FPGA deselektieren)


===DAP-Modul-Schnipsel===
===DAP-Modul-Schnipsel===


Um mal "eben" mit dem DAP zu spielen, ein paar Schnipsel die sich recht leicht zu kompletten Funktionsblöcken zusammenschließen lassen.
Um mal "eben" mit dem DAP zu spielen, ein paar Schnipsel die sich recht leicht zu kompletten Funktionsblöcken zusammenschließen lassen.
Es werden hier nur die RS232 Sequenzen mit einer kurzen Erklärung aufgelistet.
Es werden hier nur die RS232-Sequenzen mit einer kurzen Erklärung aufgelistet.


*Dual Mono Biquad
*Dual Mono Biquad


*ESC 0x00 - FPGA Selektieren
*ESC 0x00 - FPGA selektieren
*0xF1    - DAP Auswählen
*0xF1    - DAP auswählen
*0x00 0x00 0x00 - Memory Write (Adresse 0x0000 -> Program Memory)
*0x00 0x00 0x00 - Memory Write (Adresse 0x0000 -> Program Memory)
*0x10 0x00 0x00 0x08 - Biquad mit Kanal 1 (0) rechnen (AMEM = 0x00;CMEM = 0x08) und auf Kanal 1 (0) ausgeben
*0x10 0x00 0x00 0x08 - Biquad mit Kanal 1 (0) rechnen (AMEM = 0x00;CMEM = 0x08) und auf Kanal 1 (0) ausgeben
*0x10 0xf0 0x08 0x10 - Biquad mit vorherigem Ergebnis (0xf) rechnen (AMEM = 0x08; CMEM = 0x10) und auf Kanal 1 (0) ausgeben
*0x10 0xf0 0x08 0x10 - Biquad mit vorherigem Ergebnis (0xf) rechnen (AMEM = 0x08; CMEM = 0x10) und auf Kanal 1 (0) ausgeben
*0x01 0x00 0x00 0x00 - Audio Programm Ende (wichtig !!!)
*0x01 0x00 0x00 0x00 - Audioprogramm Ende (wichtig !!!)
*ESC 0x01 - DAP & FPGA deselektieren
*ESC 0x01 - DAP & FPGA deselektieren


Erklärung :
Erklärung :


Der Aufbau des Opcodes 0x100008 deutet an, das ein Biquad durchgerechnet werden soll. Das Eingangsregister 0 bedeutet das Kanal 1 des 1. Codecs verwendet wird. Das Ausgangsregister welches nach Fertigstellung des Ergebnisses benutzt werden
Der Aufbau des Opcodes 0x100008 deutet an, dass ein Biquad durchgerechnet werden soll. Das Eingangsregister 0 bedeutet, dass Kanal 1 des 1. Codecs verwendet wird. Das Ausgangsregister, welches nach Fertigstellung des Ergebnisses benutzt werden soll, ist 0 (-> Kanal 1 des 1. Codecs). Der Teil 0x00 0x08 bedeutet hierbei, dass die Biquad-Koeffizienten im CMEM ab Adresse 0x08 stehen. Die Audio-Zwischenwerte werden in den Audiospeicher AMEM ab Adresse 0x00 gelegt.
ist 0 (-> Kanal 1 des 1. Codecs). Der Teil 0x00 0x08 bedeutet hierbei, das die Biquad-Koeffizienten im CMEM ab Adresse 0x08 stehen. Die Audio-Zwischenwerte werden im Audio-Speicher AMEM ab Adresse 0x00 gelegt.
Der zweite Opcode (0x10f00810) rechnet ebenfalls ein Biquad durch. Nur dass hier statt Kanal 1 des Codecs das voher vom SDSP berechnete Ergebnis verwendet werden soll (Kanal 0xf, wenn man so will). Ausgangsregister ist auch hier wieder Kanal 1. Da dieser Biquad unabhängig vom ersten (d.h. mit anderen Parametern) gerechnet werden soll, sind hier logischerweise auch andere Adressen für AMEM (0x08) und CMEM (0x10) angegeben. Die CMEM-Adresse ist dabei etwas unkritischer, da es ja durchaus sein kann, dass ein Audiosignal zweimal mit den selben Biquad-Werten gerechnet werden soll, bzw. unterschiedliche Kanäle mit den selben Biquad-Werten, z.b. bei einem Stereo-Equalizer. Kritischer ist allerdings die Verwendung der AMEM-Adresse. Diese sollte für jede Operation (sofern AMEM denn verwendet wird) unterschiedlich sein, vor allem bei der Berechnung von Biquads. Dies hat den Grund, dass bei Operationen, die dieselben AMEM Adressen haben, die vorher berechneten Werte überschrieben werden. Dies ist bei Biquads gaanz böse (kann u.U. SEHR laut werden), und vom Ergebnis her nicht vorhersagbar.
Der zweite Opcode (0x10f00810) rechnet ebenfalls ein Biquad durch. Nur das hier statt Kanal 1 des Codecs das voher vom SDSP berechnete Ergebnis verwendet werden soll (Kanal 0xf, wenn man so will). Ausgangsregister ist auch hier wieder Kanal 1. Da dieser Biquad unabhängig vom ersten (d.h. mit anderen Parametern) gerechnet werden soll, sind hier logischerweise auch andere Adressen für AMEM (0x08) und CMEM (0x10) angegeben. Die CMEM-Adresse ist dabei etwas unkritischer, da es ja durchaus sein kann das ein Audio-Signal zweimal mit den selben Biquad-Werten gerechnet werden soll, bzw. unterschiedliche Kanäle mit den selben Biquad-Werten, z.b. bei einem Stereo-Equalizer. Kritischer ist allerdings die Verwendung der AMEM-Adresse. Diese sollte für jede Operation (sofern AMEM denn verwendet wird) unterschiedlich sein, vor allem bei der Berechnung von Biquads. Dies hat den Grund das bei Operationen, die dieselben AMEM Adressen haben die vorher berechneten Werte überschrieben werden. Dies ist bei Biquads gaanz böse (kann u.u. SEHR laut werden), und vom Ergebnis her nicht vorhersagbar.


==Hardware==
==Hardware==
Zeile 233: Zeile 228:
[[bild:Fpga_ext_board_schematic_no_uc.JPG|thumb|500px]]
[[bild:Fpga_ext_board_schematic_no_uc.JPG|thumb|500px]]


Wie Eingangs erwähnt benötigt das System eine (bzw. zwei) Audio-Codecs. Im aktuellen Schaltplan wird auf einen Mikroprozessor verzichtet. Dieser diente im System erstmal nur zu Initialisierung der Codecs. Dieser Vorgang kann nun vom PC aus gesteuert werden, da in der neuen ISE 6.2 Version 4 Leitungen herausgeführt wurden, welche per RS232 gesetzt und gelöscht werden.  
Wie eingangs erwähnt, benötigt das System eine (bzw. zwei) Audio-Codecs. Im aktuellen Schaltplan wird auf einen Mikroprozessor verzichtet. Dieser diente im System primär zu Initialisierung der Codecs. Dieser Vorgang kann nun vom PC aus gesteuert werden, da in der neuen ISE-6.2-Version 4 Leitungen herausgeführt wurden, welche per RS232 gesetzt und gelöscht werden.  
Wer das System nachbauen möchte kann entweder die TLV320AIC23B Codecs, aber auch beliebige andere Codecs verwenden, solange einer als Master und der andere als Slave arbeitet und beide auf den I2S Modus mit 64FS und 20 Bit Wortlänge eingestellt sind. Die Initialisierung dieser Codecs muß dann aber separat vorgenommen werden (wobei man dann wahrscheinlich nicht um einen uC drum herum kommt). Um das System zu Testen (Programme und Koeffizienten in den DAP einzuspielen) wird lediglich eine serielle Schnittstelle verwendet. Wer will kann aber genausogut den SPI-Modus verwenden und den DAP direkt von einem Mikrocontroller aus steuern. Zur Auswahl der verwendeten Schnittstelle (RS232 oder SPI) wird Pin 13 des B1-Connectors benutzt. Liegt dieser Pin auf GND so wird der FPGA per RS232 gesteuert. Liegt dieser Pin auf 3.3V so wird der FPGA per SPI gesteuert.
Wer das System nachbauen möchte, kann entweder die TLV320AIC23B-Codecs oder auch beliebige andere Codecs verwenden, solange einer als Master und der andere als Slave arbeitet und beide auf den I2S-Modus mit 64FS und 20-Bit-Wortlänge eingestellt sind. Die Initialisierung dieser Codecs muss dann aber separat vorgenommen werden (wobei man dann wahrscheinlich nicht um einen uC drumrum kommt). Um das System zu testen (Programme und Koeffizienten in den DAP einzuspielen), wird lediglich eine serielle Schnittstelle verwendet. Wer will, kann aber genausogut den SPI-Modus verwenden und den DAP direkt von einem Mikrocontroller aus steuern. Zur Auswahl der verwendeten Schnittstelle (RS232 oder SPI) wird Pin 13 des B1-Connectors benutzt. Liegt dieser Pin auf GND, so wird der FPGA per RS232 gesteuert. Liegt dieser Pin auf 3.3V, so wird der FPGA per SPI gesteuert.


Hier der Schaltplan meines verwendeten Audio-Boards.
Hier der Schaltplan meines verwendeten Audio-Boards.
<br clear="all" />
<br clear="all" />


Hier noch die Pin-Belegung des B1-Expansion Connectors:
Hier noch die Pinbelegung des B1-Erweiterungssteckers:


*01 GND
*01 GND
Zeile 270: Zeile 265:
==Nexys Board==
==Nexys Board==


Im SVN Repository (s.u.) gibt es eine Version des DAPs für das Nexys Board.
Im SVN-Repository (s.u.) gibt es eine Version des DAPs für das Nexys-Board.
Diese ist voll SW-Kompatibel zum alten Spartan 3 Board (allerdings z.Z. nur über RS232 steuerbar). Neu bei der Version ist das das Speicherinterface generisch ausgelegt wurde und ein einfacher SRAM-Controller für das Nexys Board PSDRAM geschrieben wurde. Durch das generische Interface ist es möglich andere Speicherarten anzubinden. Der verwendete Codec ist wie schon im bisherigen Projekt der TLV320AIC23B. Dieser wird via RS232 (6-pin Port A des Nexys Boards) über die GPO Leitungen (6-pin Port D des Nexys Boards) initialisiert. Die eigentlichen Datenleitungen des Codecs liegen an Port B (BCLK, LRCLK, DIN, DOUT).
Diese ist voll SW-kompatibel zum alten Spartan-3-Board (allerdings z.Zt. nur über RS232 steuerbar). Neu bei der Version ist, dass das Speicherinterface generisch ausgelegt wurde und ein einfacher SRAM-Controller für das PSDRAM des Nexys-Boards geschrieben wurde. Durch das generische Interface ist es möglich, andere Speicherarten anzubinden. Der verwendete Codec ist wie schon im bisherigen Projekt der TLV320AIC23B. Dieser wird via RS232 (6-pin Port A des Nexys-Boards) über die GPO Leitungen (6-pin Port D des Nexys-Boards) initialisiert. Die eigentlichen Datenleitungen des Codecs liegen an Port B (BCLK, LRCLK, DIN, DOUT).




Zeile 277: Zeile 272:


Diese Version ist voll lauffähig (wurde mit den Demos getestet).
Diese Version ist voll lauffähig (wurde mit den Demos getestet).
Die Pin Belegung für die RS232 und den Audio-Codec ist wie folgt :
Die Pinbelegung für die RS232 und den Audio-Codec ist wie folgt:


Header A : RS232 Schnittstelle<br>  
Header A : RS232-Schnittstelle<br>  


Pin 1 : RxD von MAX232<br>
Pin 1 : RxD von MAX232<br>
Zeile 289: Zeile 284:




Header B : I2S Schnittstelle für 1 Codec<br>
Header B : I2S-Schnittstelle für einen Codec<br>


Pin 1 : BitClk<br>
Pin 1 : BitClk<br>
Zeile 310: Zeile 305:
==DAP mit selbstgelötetem FPGA-Board==
==DAP mit selbstgelötetem FPGA-Board==


Auf einen Beitrag von Thomas Pototschnig hin bin ich auf sein selbstentworfenes Spartan-3-FPGA-Board (Grafikkarte) aufmerksam geworden. Thomas hat mir die Erlaubnis gegeben dieses Board für den DAP verwenden zu können und die Schaltpläne hier zu veröffentlichen. Nachdem ich von ihm noch einige Vorversionen (nur die Platinen) ergattern konnte und diese erfolgreich aufgebaut (mit Spartan 3-200 und -400) habe bin ich von diesem Board echt begeistert. Danke nochmals.
Auf einen Beitrag von Thomas Pototschnig hin bin ich auf sein selbstentworfenes Spartan-3-FPGA-Board (Grafikkarte) aufmerksam geworden. Thomas hat mir die Erlaubnis gegeben, dieses Board für den DAP zu verwenden und die Schaltpläne hier zu veröffentlichen. Nachdem ich von ihm noch einige Vorversionen (nur die Platinen) ergattern konnte und diese erfolgreich aufgebaut (mit Spartan 3-200 und -400) habe, bin ich von diesem Board echt begeistert. Danke nochmals.


[[Bild:FPGA-Board.jpg|thumb|300px|left]]
[[Bild:FPGA-Board.jpg|thumb|300px|left]]


Hier der Schaltplan und Layout.  
Hier Schaltplan und Layout.  


[[Media:miniFPGA-Board.zip]]
[[Media:miniFPGA-Board.zip]]


Das Board ist 2-seitig und die "schlimmsten" zu lötenden Bauteile sind lediglich der FPGA (QFP-144) und die beiden RAMs (SOJ36, ekelig). Der Rest ist recht einfach. Auch die Inbetriebnahme des Boards gestaltete sich recht einfach.
Das Board ist zweiseitig und die "schlimmsten" zu lötenden Bauteile sind lediglich der FPGA (QFP-144) und die beiden RAMs (SOJ36, ekelig). Der Rest ist recht einfach. Auch die Inbetriebnahme des Boards gestaltete sich problemlos.


Den Quellcode für den DAP mußte ich etwas ändern und abspecken. Durch den ineffizienten VHDL-Code der MAC-Einheit gestaltete es sich schwierig das Design synthetisierbar zu machen. Das Synthetisieren auf einem FT256 gestaltete sich einfacher. Hier ist noch Handlungsbedarf in der Form das die MAC-Einheit überarbeitet werden muß.  
Den Quellcode für den DAP musste ich etwas ändern und abspecken. Durch den ineffizienten VHDL-Code der MAC-Einheit gestaltete es sich schwierig, den Entwurf synthetisierbar zu machen. Das Synthetisieren auf einem FT256 gestaltete sich einfacher. Hier ist noch dergestalt Handlungsbedarf, dass die MAC-Einheit überarbeitet werden muss.  
Das abgespeckte Design läuft auf dem FPGA-Board mit einem Spartan 3-400 sowie auf einem Spartan 3-200.  
Der abgespeckte Entwurf läuft auf dem FPGA-Board mit einem Spartan 3-400 sowie auf einem Spartan 3-200.  
Den Audio-Codec, das FPGA Board, einen AVR und noch etwas IO-Kram habe ich auf eine Lochraster aufgebaut. Was noch fehlt ist ein MIDI und ein SD/MMC-Karten Interface. Dann hat man eine schöne Plattform für Synthesizer und Effektgerät.
Den Audio-Codec, das FPGA Board, einen AVR und noch etwas IO-Kram habe ich auf eine Lochrasterplatine aufgebaut. Was noch fehlt, sind MIDI- und SD/MMC-Karten-Schnittstellen. Dann hat man eine schöne Plattform für Synthesizer und Effektgeräte.




Zeile 330: Zeile 325:
==Anmerkung==
==Anmerkung==


Da wie schon gesagt das Projekt komplett auf meinem "Mist" gewachsen ist wird es wohl noch eine Weile dauern bis alles was den DAP betrifft hier in diesem Artikel (und auch in einem Dokumentations-PDF) eingearbeitet ist. Ich werde (sofern ich Zeit dazu habe) noch ein Delphi Programm mit Source-Code einstellen, welche den DAP richtig nutzbar macht und man dann direkt damit "spielen" kann. Eine umfangreiche und vollständige Dokumentation würde momentan einfach zu viel Zeit in Anspruch nehmen und ich möchte langsam das Projekt Vorstellen um Anregung, Kritik und Verbesserungsvorschläge ernten zu können. Ich hoffe noch Leute zu finden um diesem Projekt noch mehr Leben und Möglichkeiten einhauchen zu können.
Da, wie schon gesagt, das Projekt komplett auf meinem "Mist" gewachsen ist, wird es wohl noch eine Weile dauern, bis alles, was den DAP betrifft, hier in diesem Artikel (und auch in einem Dokumentations-PDF) eingearbeitet ist. Ich werde (sofern ich Zeit dazu habe) noch ein Delphi-Programm mit Sourcecode einstellen, welches den DAP richtig nutzbar macht, so dass man dann direkt damit "spielen" kann. Eine umfangreiche und vollständige Dokumentation würde momentan einfach zu viel Zeit in Anspruch nehmen, und ich möchte langsam das Projekt vorstellen, um Anregung, Kritik und Verbesserungsvorschläge ernten zu können. Ich hoffe, weitere Leute zu finden, um diesem Projekt noch mehr Leben und Möglichkeiten einhauchen zu können.


==Fotos==
==Fotos==
Zeile 336: Zeile 331:
Ursprüngliche Version:
Ursprüngliche Version:


[[Bild:Gesamt_wo_uc.jpg|thumb|200px|left|Spartan3 Board und Expansion Board]]
[[Bild:Gesamt_wo_uc.jpg|thumb|200px|left|Spartan.3-Board und Expansion-Board]]
[[Bild:Codecs.jpg|thumb|200px|left|Expansion Board]]
[[Bild:Codecs.jpg|thumb|200px|left|Expansion Board]]
<br clear="all" />
<br clear="all" />


Nexys-Board:
Nexys-Board:
[[Bild:dap_nexys_v1.jpg|thumb|200px|left|Nexys Board mit 1 Audio-Codec]]
[[Bild:dap_nexys_v1.jpg|thumb|200px|left|Nexys-Board mit 1 Audio-Codec]]
[[Bild:Nexys-board-gesamt.jpg|thumb|200px|left|Nexys Board mit Lochraster-Board und 2 Audio-Codec-Boards (siehe Artikel [[Audio Codec Board]])]]
[[Bild:Nexys-board-gesamt.jpg|thumb|200px|left|Nexys-Board mit Lochraster-Board und 2 Audio-Codec-Boards (siehe Artikel [[Audio Codec Board]])]]
[[Bild:Nexys-board-codecs-1.jpg|thumb|200px|left|2 Audio-Codec-Boards (siehe Artikel [[Audio Codec Board]])]]
[[Bild:Nexys-board-codecs-1.jpg|thumb|200px|left|2 Audio-Codec-Boards (siehe Artikel [[Audio Codec Board]])]]
<br clear="all" />
<br clear="all" />
Zeile 354: Zeile 349:
<br clear="all" />
<br clear="all" />


[[Bild:Dap-Synth-01.jpg|thumb|300px|left|Synth Board. DAP mit AVR,Codec, MIDI Interface, RS232 (schaltbar) und LCD]]
[[Bild:Dap-Synth-01.jpg|thumb|300px|left|Synth Board. DAP mit AVR,Codec, MIDI-Interface, RS232 (schaltbar) und LCD]]


<br clear="all" />
<br clear="all" />
Zeile 384: Zeile 379:
[[Bild:DAP mit Touch-Display.jpg|thumb|600px|left|DAP-Board mit Touch-Display]]
[[Bild:DAP mit Touch-Display.jpg|thumb|600px|left|DAP-Board mit Touch-Display]]


Diese Version des DAP hat ein Grafikdisplay incl. Touchpanel. Die Ansteuerung übernimmt der FPGA. Dort ist einer kleiner "Grafik-Prozessor" integriert der das Update des Displays und das Kopieren der Bitmaps übernimmt.
Diese Version des DAP hat ein Grafikdisplay incl. Touchpanel. Die Ansteuerung übernimmt der FPGA. Dort ist einer kleiner "Grafik-Prozessor" integriert, der das Update des Displays und das Kopieren der Bitmaps übernimmt.


<br clear="all" />
<br clear="all" />
Zeile 399: Zeile 394:
<br clear="all" />
<br clear="all" />


[[Bild:DAP Version 1.5.jpg|thumb|600px|left|Heue Hardware Version der DAP Hauptplatine]]
[[Bild:DAP Version 1.5.jpg|thumb|600px|left|Heue Hardwareversion der DAP-Hauptplatine]]


Diese Version beinhaltet folgendes : :-)  
Diese Version beinhaltet folgendes : :-)  
Zeile 420: Zeile 415:
  - 2 separaten Clock-Oszillatoren (nicht bestückt)
  - 2 separaten Clock-Oszillatoren (nicht bestückt)


... und weiterem Kleinkram (LevelShifter, LDO, Platformflash, usw ... und vielen 100nFern)
... und weiterem Kleinkram (Level-Shifter, LDO, Platform-Flash, usw ... und vielen 100nF-Kondensatoren)


Ideal zum Aufbau einer Audio-Platform.  
Ideal zum Aufbau einer Audioplattform.  




<br clear="all" />
<br clear="all" />


==Audio Demos==
==Audio-Demos==




Ein EQ-Demo mit Rosa Rauschen. Klingt wie eine Meeresbrandung.
Ein EQ-Demo mit rosa Rauschen. Klingt wie eine Meeresbrandung.


[[Media:eq_demo1.zip]]
[[Media:eq_demo1.zip]]
Zeile 439: Zeile 434:




=== MC505 Demos ===
=== MC505-Demos ===


Die folgenden Demos stammen von meiner Roland-MC505 Groovebox. Es wird einfach nur ein Werkspreset abgespielt und durch den DAP gejagt.
Die folgenden Demos stammen von meiner Roland MC505 Groovebox. Es wird einfach nur ein Werkspreset abgespielt und durch den DAP gejagt.


* [[Media:mc505-eq-demo.wav.zip|EQ-Demo]]
* [[Media:mc505-eq-demo.wav.zip|EQ-Demo]]
Zeile 448: Zeile 443:




=== Synth Board Audio Demos ===
=== Synth-Board Audio-Demos ===


Die folgenden Demos stammen vom DAP in Verbindung mit einem AVR der die Filterkoeffizientenberechnung sowie eine komplette Synthesizer-Steuerung beinhaltet, also qausi einen Synthesizer aus dem DAP macht (inkl. MIDI-Steuerung).
Die folgenden Demos stammen vom DAP in Verbindung mit einem AVR, der die Filterkoeffizientenberechnung sowie eine komplette Synthesizersteuerung beinhaltet, also quasi einen Synthesizer aus dem DAP macht (inkl. MIDI-Steuerung).


MIDI-Sequenz und Tiefpass-Filter (Filter und Modulation über MIDI gesteuert) :
MIDI-Sequenz und Tiefpassfilter (Filter und Modulation über MIDI gesteuert) :


[[Media:Dap-syn-demo-01.mp3]]
[[Media:Dap-syn-demo-01.mp3]]


Diesselbe MIDI-Sequenz mit Hochpass-Filter (Filter und Modulation ebenfalls über MIDI gesteuert) :
Dieselbe MIDI-Sequenz mit Hochpassfilter (Filter und Modulation ebenfalls über MIDI gesteuert) :


[[Media:Dap-syn-demo-02.mp3]]
[[Media:Dap-syn-demo-02.mp3]]


Ein eher Techno-ähnliches Demo, welches die Auflösung des Systems (DAP+AVR+MIDI) ein wenig zeigt.
Eine eher Techno-ähnliche Demo, welche die Auflösung des Systems (DAP+AVR+MIDI) ein wenig zeigt.


[[Media:Dap_syn_demo_03.mp3]]
[[Media:Dap_syn_demo_03.mp3]]
Zeile 489: Zeile 484:
== Änderungen ==
== Änderungen ==


* 12.07.2007: Es wurde ein generisches Speicherinterfaces welches Wartezyklen im DAP erlaubt implementiert. Dadurch kann man auf die jeweilgen Speicher des Boards eingehen. Z.Z. ist nur ein einfaches Speicherinterface für den asynchronen Betrieb des PSDRAM des Nexys Boards implementiert. Das Interface ermögicht es einen RAM Controller anzuschließen welcher z.&nbsp;B. ein quasi-Multiport RAM darstellt. Getestet wurde der Stand mit dem Nexys-1000 Board.
* 12.07.2007: Es wurde ein generisches Speicherinterfaces implementiert, welches Wartezyklen im DAP erlaubt. Dadurch kann man auf die jeweilgen Speicher des Boards eingehen. Z.Zt. ist nur eine einfaches Speicherschnittstelle für den asynchronen Betrieb des PSDRAM des Nexys-Boards implementiert. Die Schnittstelle ermöglicht den Anschluss eines RAM-Controller, welcher z.&nbsp;B. ein Quasi-Multiport-RAM darstellt. Getestet wurde der Stand mit dem Nexys-1000-Board.


==To do==
==To do==

Aktuelle Version vom 13. Februar 2017, 08:01 Uhr

von Benutzer:TheMason

Ziel

Ziel dieses Projekts ist es der Aufbau einer FPGA-basierten Plattform, mit der es möglich ist Synthesizer, Effektgeräte, Mischpulte oder gar ein Harddiskrecording-System zu realisieren.

Feature-Liste

Eigenschaften des Audioprozessors:

  • Oszillatoren
  • Biquads (Filter)
  • Addierer, Schalter, Verstärker (Multiplizierer)
  • Delays
  • Steuerung des Audioprozessors via SPI oder RS232
  • 4 Mono Ein- und Ausgänge
  • GPO (General-Purpose-Outputs) zur Konfiguration der Codecs

Übersicht

Overview wo uc.jpg

Basis des Audiosystems ist das Spartan-3-Development-Board von Xilinx. An diesem Board werden zwei Audio-Codecs angeschlossen, von denen einer als Master und der andere als Slave agiert. Optional kann noch ein Mikrocontroller angeschlossen werden, welcher den FPGA per SPI steuert. Da dieses Projekt mittlerweile recht umfangreich geworden ist, kann ich hier nur einen kurzen Umriss des Systems geben. Dabei beschränke ich mich auf die grobe Funktionsweise des Audioprozessors, erläutere die Schnittstelle (welche ich als Basis für weitere Projekte bereits nutze) und gebe einen kleinen Überblick über die Hardware.

Das System kann (sofern man zwei Audio-Codecs, von denen einer als Master, der andere als Slave arbeitet, angeschlossen und konfiguriert hat) direkt genutzt werden, da der DAP per RS232 gesteuert werden kann. Der Audioprozessor startet mit einem Stereo-Tiefpassfilter, das sich auf den ersten Codec bezieht, sodass man eine erste Demo hat (selbst wenn diese etwas unspektakulär ist)


Nachbau

Wer sich dieses System nachbauen möchte, benötigt zunächst ein FPGA-Board. Mit dem Spartan-3-Board von Digilent gestaltet sich der Nachbau einfach, weil die Programmier-Dateien für den FPGA direkt für dieses Board verwendet werden können. Nutzer anderer Boards (Xilinx) müssten zuerst die UCF-Datei für die Pins ihres jeweiligen Boards anpassen, und dieses Projekt neu synthetisieren (compilieren). Nutzer von Altera-Boards hingegen müssen die BlockRAM-Instanzen auf die Altera-Architektur anpassen (den Inhalt der RAMs dabei nicht vergessen :-). Vielleicht findet sich ja der eine oder andere der den VHDL Code für Altera-FPGAs portiert. Der eigentliche wichtige Teil eines Nachbaus ist der Codec-Teil. Dieses System verwendet zwar zwei Codecs, aber es kann auch mit einem gearbeitet werden. Als Codec kommt der TLV320AIC23B von Texas Instruments zum Einsatz. Diesen kann man als kostenloses Muster bei TI direkt bekommen. Des weiteren benötigt man noch eine handvoll Bauteile wie Kondensatoren, Widerstände und einen Quarz. (Ein Codec MUSS als Master laufen, sonst hat das System keine Audio-Clocks, da diese nicht vom FPGA generiert werden) Die Initialisierung des Codecs wird vom PC aus gemacht. Dazu dienen die 4 GPO-Leitungen auf dem B1-Verbinder. Da der Codec nur "halbes" SPI unterstüzt (man kann nur schreiben, nicht lesen) gestaltet sich die Initialisierung recht einfach. Die 4 GPO-Leitungen teilen sich folgendermaßen auf :

  • Chip-Select Codec 2
  • Chip-Select Codec 1
  • SPI Data Out
  • SPI Clock

Audio-Prozessor (DAP)

Overview dap core.JPG

Der FPGA beinhaltet in dem gesamten System einen Quasi-DSP. Quasi-DSP deshalb, da die Struktur im Gegensatz zu einem DSP bzw. Mikrocontroller keine Verzweigungen, Interrupts oder ähnliches zulässt. Der Audio-Prozessor besteht im wesentlichen aus 3 Teilen : einem Rahmen, einem SDSP (Small DSP)-Kern sowie einem Utility-Kern. Beide Kerne können theoretisch parallel arbeiten, da jeder Kern einen eigenen Zustandsautomaten und einen eigenen Microcode-Speicher besitzen. Diese Möglichkeit ist allerdings noch nicht implementiert.

Der SDSP-Kern besteht im wesentlichen aus einer MAC-Einheit, einem Speicher für Audiodaten, einem Koeffizienten-Speicher, einem Adressgenerator und mehreren Muxern, sowie dem schon angesprochenen Zustandsautomaten und dem Microcode. Weiterhin ist ein Hidden-Write- (bzw. Shadow Register) Mechanismus integriert, welcher ein "knackserfreies" Aktualisieren von Koeffizienten ermöglicht. Alle diese Komponenten werden vom Microcode aus gesteuert (genau wie bei einem Mikrocontroller). Mit diesem Kern ist es möglich, Audiosignale zu bearbeiten. Zu Den Bearbeitungsmöglichkeiten zählen in erster Linie das Verändern der Lautstärke, Mischen, Filtern (Biquad) sowie Laden und Speichern von Audiowerten.

Der Utility-Kern besteht aus einem Akkumulator (für DDS), einem Shaper, einem Adressgenerator, einem Wavetable-Speicher, einem Zufallszahlengenerator, einigen Muxern, (einem Adressgenerator für SRAM, einem SRAM-Controller; diese sind allerdings nur nutzbar, wenn man das ganze mit dem ISE 6.2 synthetisiert) und dem schon angesprochenen Zustandsautomaten und dem Microcode. Der Microcode steuert (genau wie beim SDSP-Kern) dabei die einzelnen Komponenten des Utility-Kerns. Dieser Kern ist für das Erzeugen von Audiosignalen zuständig, und erlaubt ein Audiosignal zu verzögern, sofern man die ISE-Version 6.2 verwendet (später dazu mehr). Als Wellenformen stehen Sägezahn, Rechteck (mit veränderbarer Pulsbreite), Rauschen sowie benutzderdefinierbare Wellenformen (Wavetable) zur Verfügung.

Der Rahmen besteht aus einem Zustandsautomaten, einem Programmspeicher, einigen Muxern, sowie einem doppelten I2S-Sender/Empfänger (für 2 Stereo Ein- und Ausgänge). In den Rahmen werden die beiden Kerne "eingehängt". Die Kerne werden vom Programmspeicher aus mit Daten versorgt, und vom Zustandsautomaten angesteuert. Der Programmspeicher (PMEM) ist als 512x32 Bit organisiert. Das heißt, dass ein Befehl im Programmspeicher 32 Bit an Informationen enthält und der Audioprozessor max. 512 Befehle umfassen kann.

SDSP-Core

Struktur des SDSP-Kerns

Der eigentliche Kern des DAPs ist die MAC-Einheit. Mit ihr werden die grundlegenden Operationen Multiplikation und Addition durchgeführt. Es ist eine 32x32-Bit-Einheit. Die Funktionsweise des Kerns ist eigentlich recht einfach. Die MAC-Einheit hat 2 Eingänge. Einer dieser Eingänge kann ein Audiosignal, ein Wert aus dem Audiospeicher (AMEM-BlockRAM) oder ein zuvor berechnetes Ergebnis sein. Der andere Eingang kann ein Koeffizient aus dem CMEM-BlockRAM oder eine Konstante (1.000, 0.000 oder -1.000) sein. Der Ausgang (32-Bit, hart geclippt) geht auf das AMEM-BlockRAM und zum Ausgangs-Clipping. Das Ausgangsclipping schneidet das Audiosignal auf 24-Bit zurecht. Die Adressen für die Speicher (AMEM und CMEM) werden im Addressgenerator erzeugt. Dieser wird von außen mit einer 8-Bit-Basis-Adresse gespeist und erzeugt einen Offset zu den Eingangsadressen. Er besitzt 2 setzbare Zähler und einige Multiplexer. Alle Steuersignale der Komponenten von einem weiteren aus BlockRAM (MMEM) versorgt. Weiterhin wird von außen eine Startadresse vorgegeben. Dadurch lassen sich quasi Opcodes mit von außen vorgegeben Parametern (Adressen) aufrufen. Das MMEM-BlockRAM wird nun einfach nur linear ausgelesen bis ein Stopbit gesetzt ist.



Util-Core

Struktur des Utility-Kerns

Beschreibung folgt


Opcodes des DAP

Diese 32 Bit eines Befehls teilen sich folgendermaßen auf :

  • 4 Bit = Opcode (für SDSP und Utility Kern gleich)
  • 2 Bit = noch leer
  • 1 Bit = Core Select (SDSP oder Utility)
  • 1 Bit = Ende des Programms
  • 4 Bit = Eingangsrouting (Kanal 1 - 4, Ergebnis SDSP-Kern, Ergebnis Utility-Kern)
  • 4 Bit = Ausgangsrouting (SDSP-Ausgang auf Kanal 1-4, Utility-Ausgang auf Kanal 1-4)
  • 8 Bit = Adresse 1 (bei SDSP für Audio-Memory, bei Utility-Kern für Datenspeicher)
  • 8 Bit = Adresse 2 (bei SDSP für Koeffizientenspeicher, bei Utility-Kern unbenutzt)

Das Eingangsrouting bestimmt, mit welchem Signal der gewählte Kern arbeiten soll. Dies können die Eingänge 1-4 aber auch ein vorher berechnetes Ergebnis des SDSP- bzw. Utility-Kerns sein. Das Ausgangsrouting bestimmt, von welchem Kern das Signal auf welchen Ausgang geroutet wird.

Die Opcodes des DAPs sind:

SDSP-Kern:

  • Biquad rechnen
  • Audiowert speichern
  • Audiowert laden
  • Move eines Wertes im Audiospeicher
  • Summe rücksetzen
  • Eingang zu Summe addieren
  • Wert aus dem Audiospeicher zu Summe addieren
  • Eingang zu Summe mischen (mit Lautstärkekoeffizient)
  • Wert aus dem Audiospeicher zu Summe mischen (mit Lautstärkekoeffizient)
  • Lautstärke

Utility-Kern:

  • Oszillator (DDS-Teil)
  • Waveshaper
  • Verzögerung

Der Ablauf eines Audio-Programms ist folgender:

Sobald ein neues Sample anliegt, wird die Abarbeitung des Programms von Adresse 0x0000 an im PMEM angestoßen. Es wird dabei jeweils ein Befehl geladen und Daten wie Opcode und Adressen liegen dabei an beide Kernen gleichermaßen an. Ist das Programm-Ende-Bit nicht gesetzt, so wird der jeweilige Kern (mit dem im Opcode angegeben Routing) angesteuert. Legt der betreffende Kern sein Ready-Signal auf 1, so wird der nächste Befehl abgearbeitet. Dieses Verhalten (Laden und Verteilen von Opcode-Daten sowie die Ablaufsteuerung, also das Ansteuern des Programms, Ansteuern der einzelnen Kerne, warten auf dessen Abarbeitung und das Programmende) wird vom Rahmen übernommen.

Speicherorganisation

Alle Speicher die vom DAP angesprochen werden, haben eine Wortbreite von 32 Bit, der Zugriff erfolgt aber ausschließlich über eine Breite von 8 Bit (Interface).

DAP

  • Programmspeicher (PMEM) 0x0000 - 0x07ff

SDSP

  • Audiospeicher (AMEM) von außen nicht zugänglich
  • Koeffizientenspeicher (CMEM) 0x2000 - 0x2023 (man "sieht" nur den Hidden Write -> später mehr dazu)
  • Microcodespeicher (MMEM) 0x4000 - 0x47ff

Utility-Core

  • Datenspeicher (DMEM) 0x6000 - 0x67ff
  • Wavetable-Speicher (WMEM) 0x8000 - 0x87ff
  • Microcodespeicher (UMEM) 0xa000 - 0xa7ff

Hidden-Write

Um bei Änderung der Koeffizienten Knackser zu vermeiden (die dadurch entstehen, dass der Koeffizient nur teilweise [durch 8-Bit-Zugriffe] geändert wird, währenddessen aber Audio trotzdem noch "weiterläuft" und mit "falschen" Zwischenwerten gerechnet wird), ist ein Mechanismus implementiert, der die zu ändernden Koeffizienten im Hintergund in den Speicher schreibt. Um diesen Mechanismus zu nutzen, müssen zuerst die Koeffizienten in interne Register geschrieben werden. Die Register (es sind 8 32-Bit-Register) liegen im Speicherbereich 0x2000 bis 0x201f. Die Speicherstelle 0x2020 gibt die Startadresse innerhalb des Koeffizientenspeichers an. Diese Adresse ist nur 8 Bit breit. Die Speicherstelle 0x2021 gibt an, wieviele der 8 Register übertragen werden sollen. Die Speicherstelle 0x2022 löst den Kopiervorgang aus. Hier reicht es, ein Dummy-Byte zu schreiben. Um den Kopiervorgang zu beenden (MUSS GEMACHT WERDEN, sonst können keine weiteren Koeffizientenupdates gemacht werden), schreibt man an Speicherstelle 0x2023 ebenfalls ein Dummy-Byte.

I/O Register

Es gibt noch einen 8-Bit breiten Adressbereich innerhalb des DAPs, mit dem der I2S-Teil stummgeschaltet werden kann. Weiterhin hat man die Möglichkeit, die Anzahl der Systemtakte pro Sample und die Anzahl der aktiven Systemtakte (also die Zeit die der Audioprozessor beschäftigt ist) zu ermitteln. Dadurch lässt sich eine Auslastungsanzeige des DAPs realisieren.

Interface

Um von außen nun ein Programm (bzw. Koeffizienten und Daten) zu laden, ist eine einfach zu handhabende und erweiterbare Schnittstelle implementiert. Die Schnittstelle kann per RS232 (fest eingestellt auf 115,2kBaud) oder per SPI (wird hardwaremäßig eingestellt) angesteuert werden. Die Schnittstelle in ihrer Gesamtheit ist schichtweise aufgebaut und beginnt mit einem Daten-Dispatcher. Dieser Daten-Dispatcher entscheidet (nachdem dieser selektiert wurde) mit dem ersten Byte, an welches angeschlossene Gerät der weitere Datenstrom geleitet wird.

Als angeschlossene Geräte sind im aktuellen Entwurf ein Gerät namens "StdIO" und der Audioprozessor verfügbar.

Das "StdIO"-Gerät steuert die 7-Segment-Anzeige (16-Bit-Hexadezimalanzeige oder 32-Bit-Einzelsegmentanzeige) sowie die 8 Leuchtdioden, und erlaubt es, die 3 Drucktaster sowie die 8 Schiebeschalter auszulesen.

Der Audioprozessor besteht (schnittstellenseitig) nur aus einer Speicherzugriffsschnittstelle. Diese Schnittstelle entscheidet mit dem ersten Byte (sobald es selektiert wurde), ob in den Speicher geschrieben, von diesem gelesen, ein I/O-Schreib- oder -Lesezugriff erfolgen soll. Die folgenden 2 Bytes (im Falle eines I/O-Zugriffs nur 1 Byte) bestimmen die Adresse und damit den Speicherbereich des Audioprozessors, auf den zugegriffen werden soll. Die Speicherschnittstelle besitzt einen Autoinkrementierer, mit dem fortlaufende Bytes einfach hintereinander geschrieben werden können, ohne dass jedes mal wieder der FPGA, das Gerät und die neue Adresse neu geschrieben werden müssen, was den Zugriff erheblich beschleunigt.

Ursprünglich basierte das System auf einem SPI-Interface. Dabei wurde die Chip-Select-Leitung als "globaler" Interface-Reset betrachtet, d.h. war die Leitung auf High, war der FPGA deselektiert und und alle Interface-Zustandsautomaten wurden im Reset gehalten. Erst mit dem Setzen dieser Leitung wurde der FPGA angesprochen. (erstes Byte -> Daten-Dispatcher, folgende Bytes gehen an das ausgewählte Gerät). Weiterhin hat SPI die Eigenschaft, dass mit jedem gesendeten Byte auch eines empfangen wurde. Der Umstand, dass RS232 weder eine Chip-Select Leitung benötigt noch eine synchrone Übertragung erzwingt, führt zu dem Umstand, dass man bei Nutzung von RS232 einige Befehle zusätzlich benötigt. Diese Befehle werden durch das Zeichen 0x1b (ESC) eingeleitet. Soll statt der "Spezialfunktion" das Byte 0x1b übertragen werden, so wird dieses einfach erneut gesendet. Soll die Chip-Select-Leitung gesetzt bzw. gelöscht werden, so wird die Sequenz 0x1b 0x00 (Selektieren) bzw. 0x1b 0x01 (Deselektieren) gesendet. Soll ein zuvor im Ausgangsregister gesetztes Byte gesendet werden, so muss die Sequenz 0x1b 0x02 gesendet werden.

Beispiele:

0x121b auf dem 7-Segment-Display per RS232 anzeigen:

  • - ESC 0x00 (FPGA selektieren)
  • - 0xf0 (StdIO selektieren)
  • - 0x00 (Hi-Byte der 7-Segment-Hex-Anzeige wählen)
  • - 0x12 (Wert 12)
  • - ESC 0x01 (FPGA deselektieren)
  • - ESC 0x00 (FPGA selektieren)
  • - 0xf0 (StdIO selektieren)
  • - 0x01 (Lo-Byte der 7-Segment-Hex-Anzeige wählen)
  • - 0x1b 0x1b (Wert 1b -> zu beachten: wenn der Wert 0x1b übertragen werden soll, muss dieser doppelt gesendet werden !!)
  • - ESC 0x01 (FPGA deselektieren)

Beispiel, um in den Programmspeicher des Audioprozessors an Adresse 0x0010 das Langwort 0x12233445 zu schreiben:

  • - ESC 0x00 (FPGA selektieren)
  • - 0xf1 (DAP selektieren)
  • - 0x00 (Speicher schreiben)
  • - 0x00
  • - 0x10 (Adresse 0x0010 -> PMEM-Adresse 0x010)
  • - 0x12 (Adresse 0x0010 -> 0x12)
  • - 0x23 (Adresse 0x0011 -> 0x23, autoincrement)
  • - 0x34 (Adresse 0x0012 -> 0x34, autoincrement)
  • - 0x45 (Adresse 0x0013 -> 0x45, autoincrement)
  • - ESC 0x01 (FPGA deselektieren)

Auslesen der 8 Schalter:

  • - ESC 0x00 (FPGA selektieren)
  • - 0xf0 (StdIO selektieren)
  • - 0x04 (Schalter auslesen)
  • - 0x00 (dummy byte -> überträgt Schalterstellung in Ausgaberegister)
  • - ESC 0x02 (Ausgaberegister übertragen, danach empfängt man die 8 Schalterstellungen binärcodiert)
  • - ESC 0x01 (FPGA deselektieren)

Der Datendispatcher (welcher mit dem ersten Byte nach dem Selektieren des FPGAs [0x1b 0x00] angesprochen wird) hat weiterhin einige nützliche Funktionen, die in ihrer Gesamtheit allerdings noch nicht ausführlich getestet wurden. Darunter sind Funktionen, mit denen Informationen über die an den Ports des Daten-Dispatchers angeschlossenen Geräte zu ermitteln. Diese Funktion kann dazu genutzt werden, um zu ermitten, welche Geräte im FPGA implementiert sind und an welchen Ports welche Geräte angeschlossen sind.

Anzahl der Ports des Daten-Dispatchers liefern:

  • - ESC 0x00 (FPGA selektieren)
  • - 0xed (Anzahl Ports lesen)
  • - 0x00 (dummy byte -> überträgt Inhalt des Ausgaberegisters)
  • - ESC 0x02 (Ausgaberegister übertragen, danach empfängt man 0x22)
  • - ESC 0x01 (FPGA deselektieren)

DAP-Modul-Schnipsel

Um mal "eben" mit dem DAP zu spielen, ein paar Schnipsel die sich recht leicht zu kompletten Funktionsblöcken zusammenschließen lassen. Es werden hier nur die RS232-Sequenzen mit einer kurzen Erklärung aufgelistet.

  • Dual Mono Biquad
  • ESC 0x00 - FPGA selektieren
  • 0xF1 - DAP auswählen
  • 0x00 0x00 0x00 - Memory Write (Adresse 0x0000 -> Program Memory)
  • 0x10 0x00 0x00 0x08 - Biquad mit Kanal 1 (0) rechnen (AMEM = 0x00;CMEM = 0x08) und auf Kanal 1 (0) ausgeben
  • 0x10 0xf0 0x08 0x10 - Biquad mit vorherigem Ergebnis (0xf) rechnen (AMEM = 0x08; CMEM = 0x10) und auf Kanal 1 (0) ausgeben
  • 0x01 0x00 0x00 0x00 - Audioprogramm Ende (wichtig !!!)
  • ESC 0x01 - DAP & FPGA deselektieren

Erklärung :

Der Aufbau des Opcodes 0x100008 deutet an, dass ein Biquad durchgerechnet werden soll. Das Eingangsregister 0 bedeutet, dass Kanal 1 des 1. Codecs verwendet wird. Das Ausgangsregister, welches nach Fertigstellung des Ergebnisses benutzt werden soll, ist 0 (-> Kanal 1 des 1. Codecs). Der Teil 0x00 0x08 bedeutet hierbei, dass die Biquad-Koeffizienten im CMEM ab Adresse 0x08 stehen. Die Audio-Zwischenwerte werden in den Audiospeicher AMEM ab Adresse 0x00 gelegt. Der zweite Opcode (0x10f00810) rechnet ebenfalls ein Biquad durch. Nur dass hier statt Kanal 1 des Codecs das voher vom SDSP berechnete Ergebnis verwendet werden soll (Kanal 0xf, wenn man so will). Ausgangsregister ist auch hier wieder Kanal 1. Da dieser Biquad unabhängig vom ersten (d.h. mit anderen Parametern) gerechnet werden soll, sind hier logischerweise auch andere Adressen für AMEM (0x08) und CMEM (0x10) angegeben. Die CMEM-Adresse ist dabei etwas unkritischer, da es ja durchaus sein kann, dass ein Audiosignal zweimal mit den selben Biquad-Werten gerechnet werden soll, bzw. unterschiedliche Kanäle mit den selben Biquad-Werten, z.b. bei einem Stereo-Equalizer. Kritischer ist allerdings die Verwendung der AMEM-Adresse. Diese sollte für jede Operation (sofern AMEM denn verwendet wird) unterschiedlich sein, vor allem bei der Berechnung von Biquads. Dies hat den Grund, dass bei Operationen, die dieselben AMEM Adressen haben, die vorher berechneten Werte überschrieben werden. Dies ist bei Biquads gaanz böse (kann u.U. SEHR laut werden), und vom Ergebnis her nicht vorhersagbar.

Hardware

Fpga ext board schematic no uc.JPG

Wie eingangs erwähnt, benötigt das System eine (bzw. zwei) Audio-Codecs. Im aktuellen Schaltplan wird auf einen Mikroprozessor verzichtet. Dieser diente im System primär zu Initialisierung der Codecs. Dieser Vorgang kann nun vom PC aus gesteuert werden, da in der neuen ISE-6.2-Version 4 Leitungen herausgeführt wurden, welche per RS232 gesetzt und gelöscht werden. Wer das System nachbauen möchte, kann entweder die TLV320AIC23B-Codecs oder auch beliebige andere Codecs verwenden, solange einer als Master und der andere als Slave arbeitet und beide auf den I2S-Modus mit 64FS und 20-Bit-Wortlänge eingestellt sind. Die Initialisierung dieser Codecs muss dann aber separat vorgenommen werden (wobei man dann wahrscheinlich nicht um einen uC drumrum kommt). Um das System zu testen (Programme und Koeffizienten in den DAP einzuspielen), wird lediglich eine serielle Schnittstelle verwendet. Wer will, kann aber genausogut den SPI-Modus verwenden und den DAP direkt von einem Mikrocontroller aus steuern. Zur Auswahl der verwendeten Schnittstelle (RS232 oder SPI) wird Pin 13 des B1-Connectors benutzt. Liegt dieser Pin auf GND, so wird der FPGA per RS232 gesteuert. Liegt dieser Pin auf 3.3V, so wird der FPGA per SPI gesteuert.

Hier der Schaltplan meines verwendeten Audio-Boards.

Hier noch die Pinbelegung des B1-Erweiterungssteckers:

  • 01 GND
  • 02 VCC 5V
  • 03 VCC 3.3V
  • 04 N.C.
  • 05 SPI_CS - Chip Select (von uC nach FPGA)
  • 06 N.C.
  • 07 SPI_DI - SPI Data In (von uC nach FPGA)
  • 08 BCLK - Bit Clock (von Master Codec)
  • 09 SPI_CLK - SPI Clock (von uC nach FPGA)
  • 10 LRCLK - LR-Clock (von Master Codec)
  • 11 SPI_DO - SPI Data Out (von FPGA nach uC)
  • 12 SDOUT1 - zum D/A Wandler (Codec) 1
  • 13 IF_SEL - Interface Select (GND = RS232; VCC3.3 = SPI)
  • 14 SDIN1 - vom A/D Wandler (Codec) 1
  • 15 RXD_OUT - RS232 Signal vom MAX232 zum uC
  • 16 SDIN2 - vom A/D Wandler (Codec) 2
  • 17 TXD_IN - RS232 Signal vom uC zum MAX232
  • 18 SDOUT2 - zum D/A Wandler (Codec) 2
  • 19 GPO 3 - Chip-Select Codec 2
  • 20 N.C.
  • 19 GPO 2 - Chip-Select Codec 1
  • 20 N.C.
  • 19 GPO 1 - SPI-Data out
  • 20 N.C.
  • 19 GPO 0 - SPI-Clock Out
  • 20 N.C.

Nexys Board

Im SVN-Repository (s.u.) gibt es eine Version des DAPs für das Nexys-Board. Diese ist voll SW-kompatibel zum alten Spartan-3-Board (allerdings z.Zt. nur über RS232 steuerbar). Neu bei der Version ist, dass das Speicherinterface generisch ausgelegt wurde und ein einfacher SRAM-Controller für das PSDRAM des Nexys-Boards geschrieben wurde. Durch das generische Interface ist es möglich, andere Speicherarten anzubinden. Der verwendete Codec ist wie schon im bisherigen Projekt der TLV320AIC23B. Dieser wird via RS232 (6-pin Port A des Nexys-Boards) über die GPO Leitungen (6-pin Port D des Nexys-Boards) initialisiert. Die eigentlichen Datenleitungen des Codecs liegen an Port B (BCLK, LRCLK, DIN, DOUT).


Diese Version ist voll lauffähig (wurde mit den Demos getestet). Die Pinbelegung für die RS232 und den Audio-Codec ist wie folgt:

Header A : RS232-Schnittstelle

Pin 1 : RxD von MAX232
Pin 2 : TxD von MAX232
Pin 3 : -
Pin 4 : -
Pin 5 : GND
Pin 6 : VCC (3.3V/5V für MAX232/MAX3232)


Header B : I2S-Schnittstelle für einen Codec

Pin 1 : BitClk
Pin 2 : L/R Clk
Pin 3 : SDIN
Pin 4 : SDOUT
Pin 5 : GND
Pin 6 : VCC (3.3V für den Codec)


Header D : Codec-Konfiguration via SPI

Pin 1 : Codec 2 CS
Pin 2 : Codec 1 CS
Pin 3 : Codec SPI Data
Pin 4 : Codec SPI Clk
Pin 5 : GND
Pin 6 : VCC

DAP mit selbstgelötetem FPGA-Board

Auf einen Beitrag von Thomas Pototschnig hin bin ich auf sein selbstentworfenes Spartan-3-FPGA-Board (Grafikkarte) aufmerksam geworden. Thomas hat mir die Erlaubnis gegeben, dieses Board für den DAP zu verwenden und die Schaltpläne hier zu veröffentlichen. Nachdem ich von ihm noch einige Vorversionen (nur die Platinen) ergattern konnte und diese erfolgreich aufgebaut (mit Spartan 3-200 und -400) habe, bin ich von diesem Board echt begeistert. Danke nochmals.

FPGA-Board.jpg

Hier Schaltplan und Layout.

Media:miniFPGA-Board.zip

Das Board ist zweiseitig und die "schlimmsten" zu lötenden Bauteile sind lediglich der FPGA (QFP-144) und die beiden RAMs (SOJ36, ekelig). Der Rest ist recht einfach. Auch die Inbetriebnahme des Boards gestaltete sich problemlos.

Den Quellcode für den DAP musste ich etwas ändern und abspecken. Durch den ineffizienten VHDL-Code der MAC-Einheit gestaltete es sich schwierig, den Entwurf synthetisierbar zu machen. Das Synthetisieren auf einem FT256 gestaltete sich einfacher. Hier ist noch dergestalt Handlungsbedarf, dass die MAC-Einheit überarbeitet werden muss. Der abgespeckte Entwurf läuft auf dem FPGA-Board mit einem Spartan 3-400 sowie auf einem Spartan 3-200. Den Audio-Codec, das FPGA Board, einen AVR und noch etwas IO-Kram habe ich auf eine Lochrasterplatine aufgebaut. Was noch fehlt, sind MIDI- und SD/MMC-Karten-Schnittstellen. Dann hat man eine schöne Plattform für Synthesizer und Effektgeräte.



Anmerkung

Da, wie schon gesagt, das Projekt komplett auf meinem "Mist" gewachsen ist, wird es wohl noch eine Weile dauern, bis alles, was den DAP betrifft, hier in diesem Artikel (und auch in einem Dokumentations-PDF) eingearbeitet ist. Ich werde (sofern ich Zeit dazu habe) noch ein Delphi-Programm mit Sourcecode einstellen, welches den DAP richtig nutzbar macht, so dass man dann direkt damit "spielen" kann. Eine umfangreiche und vollständige Dokumentation würde momentan einfach zu viel Zeit in Anspruch nehmen, und ich möchte langsam das Projekt vorstellen, um Anregung, Kritik und Verbesserungsvorschläge ernten zu können. Ich hoffe, weitere Leute zu finden, um diesem Projekt noch mehr Leben und Möglichkeiten einhauchen zu können.

Fotos

Ursprüngliche Version:

Spartan.3-Board und Expansion-Board
Expansion Board


Nexys-Board:

Nexys-Board mit 1 Audio-Codec
Nexys-Board mit Lochraster-Board und 2 Audio-Codec-Boards (siehe Artikel Audio Codec Board)
2 Audio-Codec-Boards (siehe Artikel Audio Codec Board)


Aufbau von Benutzer:Andreas:

Nexys + Breadboard + 1 Audio Codec Board


Aufbau des DAPs mit FPGA-Board (entworfen von Thomas Pototschnig) auf Lochraster an AVR, Codec und weiterer IO


Synth Board. DAP mit AVR,Codec, MIDI-Interface, RS232 (schaltbar) und LCD


Synth Board. Komplettansicht


Synth Board. Synth-Board


Selbstgeroutetes DAP-Board


Selbstgeroutetes DAP-Board


Selbstgeroutetes DAP-Board auf Trägerplatine


DAP-Board mit Touch-Display Seitenansicht


DAP-Board mit Touch-Display

Diese Version des DAP hat ein Grafikdisplay incl. Touchpanel. Die Ansteuerung übernimmt der FPGA. Dort ist einer kleiner "Grafik-Prozessor" integriert, der das Update des Displays und das Kopieren der Bitmaps übernimmt.


DAP Synthesizer Ansicht 1.jpg

Synth-Board. Komplettansicht in einem Cherry-Tastaturgehäuse (wie dafür gemacht :-)) im Synthesizer-Stil


Fertige Version des DAP als Synthesizer

Der komplette Synthesizer mit schicker Frontplatte und passendem (oben schon erwähnten :-)) Cherry-Tastatur-Gehäuse.


Heue Hardwareversion der DAP-Hauptplatine

Diese Version beinhaltet folgendes : :-)

- Xilinx XC3S400
- ATmega2561
- 16 MByte (8Mx16) SDRAM
- µSD Card Slot
- AT45DB321 DataFlash
- 24C512 EEProm
- TLC320AI23B Audio Codec mit Kopfhörer Ausgang
- CS5343 A/D Wandler
- CS4344 D/A Wandler
- MIDI
- RS232
- etlichen IO-Pins vom AVR und FPGA
- 2 separaten Clock-Oszillatoren (nicht bestückt)

... und weiterem Kleinkram (Level-Shifter, LDO, Platform-Flash, usw ... und vielen 100nF-Kondensatoren)

Ideal zum Aufbau einer Audioplattform.



Audio-Demos

Ein EQ-Demo mit rosa Rauschen. Klingt wie eine Meeresbrandung.

Media:eq_demo1.zip

Der DAP als Synth. Der DAP wird komplett vom PC aus gesteuert (Hüllkurve, Sequencer und Filterberechnung werden im PC gemacht).

Media:synthdemo1.wav.zip


MC505-Demos

Die folgenden Demos stammen von meiner Roland MC505 Groovebox. Es wird einfach nur ein Werkspreset abgespielt und durch den DAP gejagt.


Synth-Board Audio-Demos

Die folgenden Demos stammen vom DAP in Verbindung mit einem AVR, der die Filterkoeffizientenberechnung sowie eine komplette Synthesizersteuerung beinhaltet, also quasi einen Synthesizer aus dem DAP macht (inkl. MIDI-Steuerung).

MIDI-Sequenz und Tiefpassfilter (Filter und Modulation über MIDI gesteuert) :

Media:Dap-syn-demo-01.mp3

Dieselbe MIDI-Sequenz mit Hochpassfilter (Filter und Modulation ebenfalls über MIDI gesteuert) :

Media:Dap-syn-demo-02.mp3

Eine eher Techno-ähnliche Demo, welche die Auflösung des Systems (DAP+AVR+MIDI) ein wenig zeigt.

Media:Dap_syn_demo_03.mp3

Delphi Tools

Um den DAP nutzbar zu machen benötigt man entweder ein uC Programm oder ein PC Programm. Da das verwenden von PC-Programmen einfacher fürs Spielen und Experimentieren ist, werde ich hier im Laufe der Zeit kleine Demo-Programme aber auch komplette Front-Ends für den DAP reinstellen. Die Delphi-Programme sind allesamt in Turbo-Delphi geschrieben und die dazugehörigen Quellcodes werden ebenfalls im Laufe der Zeit geuploaded. Ich werde allerdings zuerst noch das Feature des Konfigurierens der Codecs vom PC aus einbauen. Nachtrag zum Konfigurieren des Codecs : Prinzipiell funktioniert es, allerdings ist das mit häßlichen Nebengeräuschen verbunden, da ich bei jeder Änderung der Lautstärke im Codec, diesen auch Resetten muß, da sonst immer beide Codecs beschrieben werden, was unschön ist. Warum dies so ist kann ich leider nicht sagen, da ich keine Möglichkeit habe die SPI-Leitungen mitzusniffen (bräuchte dafür einen kleinen LA, den ich nicht habe).


Es folgen noch der Quellcode für den Mischer (hab ich gerade nicht zur Hand) und weitere Demos (ein Synthesizer und eine 4x4 Patchbay mit EQ und was mir sonst noch einfällt. Dann natürlich mit Source-Codes). Anhand dieser Beispiele wird auch eine grobe Doku erstellt.

SVN-Repository

svn co svn://mikrocontroller.net/audiodsp

Ein automatisch aktualisiertes Paket mit den Daten aus dem Repository gibt es unter http://www.mikrocontroller.net/download/audiodsp-snapshot.tar.gz.


Änderungen

  • 12.07.2007: Es wurde ein generisches Speicherinterfaces implementiert, welches Wartezyklen im DAP erlaubt. Dadurch kann man auf die jeweilgen Speicher des Boards eingehen. Z.Zt. ist nur eine einfaches Speicherschnittstelle für den asynchronen Betrieb des PSDRAM des Nexys-Boards implementiert. Die Schnittstelle ermöglicht den Anschluss eines RAM-Controller, welcher z. B. ein Quasi-Multiport-RAM darstellt. Getestet wurde der Stand mit dem Nexys-1000-Board.

To do

  • nähere Zukunft
    • Einen Konfigurationsdialog in die Demo-Programme einarbeiten mit denen man mit den Codecs etwas spielen kann (Line-In Level, Mikrofon-Level, Bypass, Head-Phone Volume) tlw. erledigt. Funktioniert aber nicht richtig, und daher noch nicht eingebaut. Quellcodes dazu sind vorhanden.
    • Doku anhand der Demo-Programme erstellen
    • C-Code schnipsel erstellen
  • fernere Zukunft
    • Front-End des DAPs machen, mit dem sich DAP-Programme erstellen lassen, der Koeffizienten-, Daten- und Wellenform-Speicher beschrieben und gelesen werden kann, der Mikro-Code editierbar gemacht wird und noch ein paar Sachen mehr machbar sind
    • weitere Module für den Rahmen (HDD-Core, weitere Routing-Möglichkeiten innerhalb der bisherigen Cores SDSP und Util)

Diskussion

Falls Interesse an einer Sammelbestellung für die Platinen und Bauteile besteht