[[dtpr_sram_echo]]

Im Digitaltechnik Repository gibt es das de1_audio Projekt. In dem Design wird der Wolfson Audio Codec WM8731 verwendet um die Audiodaten vom Mikrofon kontinuierlich im On-Chip RAM auf dem FPGA zu speichern und dann zeitversetzt wieder auszugeben. Das ergibt einen Echoeffekt.

Der WM8731 Wolfson Audio Codec hat eine I2C Konfigurationsschnittstelle und eine serielle Audiodatenschnittstelle. Auf dem FPGA wird im Modul audio.vhd die Konfiguration über I2C durchgeführt und die seriellen Audiodaten werden seriell/parallel gewandelt und stehen dann als 16 Bit Datenworte zur Verfügung. Die Audiodaten werden im Modul ringbuf.vhd zwischengespeichert und mit Verzögerung wieder ausgelesen. Die beiden Module sind auf dem de1_audio.vhd toplevel zusammengeschaltet.

  • Starten Sie die die Simulation des de1_audio Moduls. Zeigen Sie im Simulator, dass das adc_valid anzeigt wenn ein neues Audiosample vom Audio Codec ankommt. Zeigen Sie, dass die Audiosamples mit einer Datenrate von ungefähr 48 kSamples/s ankommen.
  • Erläutern Sie die Funktion des Moduls ringbuf.
  • Starten Sie die Synthese und zeigen Sie, dass die Audiosamples im FPGA On-Chip RAM gespeichert werden. Wie groß ist der verfügbare FPGA On-Chip Speicher und wieviel von diesem Speicher wird für das Design verwendet?
  • Berechnen Sie die Echozeit, die mit diesem Design erreicht wird.
  • Laden Sie das Design auf das FPGA und überprüfen Sie die Funktion mit dem Headset.

Auf dem Terasic DE1 FPGA Board befindet sich ein IS61WV25616 statisches SRAM. Dieses SRAM soll eingesetzt werden um die Echozeit zu verlängern. Dazu sollen die Audiosamples nicht mehr im On-Chip RAM sondern im externen RAM zwischengespeichert werden.

  • Ermitteln Sie die Speichergröße des externen SRAM und berechnen Sie die mögliche Echozeit.

Für den Zugriff auf das SRAM müssen die Steuersignale des SRAM in einer geeigneten Weise angesteuert werden. Der Zugriff muss so erfolgen, dass alle Timingparameter des SRAMs sicher berücksichtigt werden. Dies soll mit einem Zustandsautomaten erfolgen.

Das externe SRAM ist ein asynchrones SRAM mit einem bidirektionalen 16 Bit Datenbus. Bei einem Schreibzugriff werden die Datenleitung vom FPGA getrieben und bei einem Lesezugriff werden die Datenleitungen vom SRAM getrieben. Dazu muss auf dem FPGA ein Tri-State Treiber eingesetzt werden.

signal io : std_logic_vector(15 downto 0)
signal wdata,rdata : std_ulogic_vector(15 downto 0);
signal trien : std_ulogic;
...
io <= wdata when trien = '1' else (others => 'Z');
rdata <= io;

Im Codebeispiel wird ein Tri-State Treiber für das bidirektionale Signal “io” eingesetzt. Beachten Sie, dass der Typ std_logic_vector ist, weil dieses Signal mehrere Treiber hat. Im folgenden Beispielcode wird an der entity von de1_audio der Port SRAM_DQ mit der Portrichtung “inout” beschrieben. Damit ist dies ein bidirektionaler Port.

entity de1_audio is 
  port (
    CLOCK_50:   in std_ulogic;
    KEY0:       in std_ulogic;
    SRAM_DQ :   inout std_logic_vector(15 downto 0);
    I2C_SCLK:   out std_ulogic;
    ...

In der Gesamtschaltung ist dann ein Tri-State Treiber auf dem FPGA und ein Tri-State Treiber auf dem SRAM. Die beiden Treiber können auf die gleiche Leitung treiben. Wenn beide Tri-State Treiber gleichzeitig treiben, dann entsteht ein Kurzschluss wenn eine Seite einen Highpegel und die andere Seite eine Lowpegel treibt. Deshalb muss verhindert werden, dass beide Seiten gleichzeitig treiben.

Gleichzeitig dürfen auch nicht beide Seiten für einen langen Zeitraum nicht treiben, da dann die Leitung hochohmig ist. Durch parasitäte Widerstände kann es auf der Leitung zu Spannungswerten kommen bei denen die Eingangstreiber an der Tri-State Leitung in einen ungünstigen Betriebszustand kommen weil dann sowohl der PMOS als auch der NMOS Transistor teilweise leiten. Deshalb muss man folgendes sicherstellen:

  • Niemals beide Treiber gleichzeitig treiben lassen (Kurzschluss)
  • Beide Treiber dürfen nur kurzzeitig für weniger als 100 ns gleichzeitig nicht treiben

Weil die Timingverifikation von Tri-State Leitungen nicht ganz einfach ist, sollen alle Tristatebuffer ausschliesslich auf dem Toplevel realisiert werden. Bidirektionale Ports sollen ausschliesslich auf dem Toplevel vorkommen.

Das SRAM hat die Steuersignale “CEN, OEN, WEN, UBN, LBN”. Finden Sie anhand des Datenblatts des SRAMs heraus wie man einen Lese- und einen Schreibzugriff auf das RAM machen kann. Berücksichtigen Sie dabei die Timingparameter des RAM. Im Datenblatt des SRAM sind beispielsweise in der Tabelle “READ CYCLE SWITCHING CHARACTERISTICS” auf Seite 6 verschiedene Werte für “-8, -10, -20” angegeben. Dabei handelt es sich um verschiedenen Speedgrades des RAM, d.h. man kann den Speicher in verschiedenen Geschwindigkeitsklassen kaufen. Dabei ist “-8” das schnellste und “-20” das langsamste RAM. Nehmen Sie für Ihre Überlegungen an, dass Sie das langsamste RAM vom Typ “-20” einsetzen. Auf dem Board befindet sich ein RAM vom Typ “-10”.

Nehmen Sie an, dass alle Daten- und Steuerleitungen des SRAM vom FPGA aus mit Registern angesteuert werden, die mit dem 50 MHz Clock arbeiten. Die Steuerleitungen werden vom FPGA aus mit einem noch zu konstruierenden Steuerautomaten angesteuert. Deshalb können Sie die Leitungen im Raster der Taktperiodendauer von 20ns verändern.

  • Wählen Sie einen geeigneten Betriebszustand wenn weder ein Schreib- noch ein Lesezugriff auf das RAM erfolgen soll. Welchen Wert haben dann die Steuerleitungen?
  • Welche Steuerleitungen können Sie permanent auf einen konstanten Wert setzen? Auf welchen Wert?

Wenn Sie den Wert eines Steuersignals verändern, dann muss diese Änderung vom Register aus ggf. noch durch eine Ausgangslogik und durch einen Pin des FPGA. Nehmen Sie für jedes Signal, das in das FPGA oder aus dem FPGA geht eine Verzögerung von 4-6ns bezüglich des Taktsignals an.

Bei einem Lesezugriff müssen die Daten vom SRAM in ein Register auf dem FPGA übernommen werden. Dieses Register muss mit einem Enablesignal zu einem geeigneten Zeitpunkt enabled werden wenn die gültigen Lesedaten am D-Eingang des Registers anliegen. Das Enablesignal für das Register soll auch aus dem noch zu konstruierenden Steuerautomaten kommen.

  • Zeichnen Sie ein Timingdiagramm für einen Lesezugriff. Im Timingdiagramm soll der Systemtakt, die Steuerleitungen für das SRAM, das Enablesignal für den Tri-State Treiber auf dem FPGA, das Enablesignal für das Leseregister und die Adress- und Datenleitungen zu sehen sein.
  • Zeichnen Sie ein Timingdiagramm für einen Schreibzugriff

Für das Echo muss jedes Audiosample im SRAM gespeichert werden. Immer wenn ein neues Audiosample ankommt, dann soll

  • Das alte Audiosample aus dem SRAM gelesen werden
  • Das neue Audiosample in das SRAM geschrieben werden

Das SRAM soll dabei als Ringbuffer organisiert werden, d.h. es gibt einen Adresszeiger, der mit einer Modulofunktion für jedes ankommende Audiosample hochzählt. Diese Adresse wird dann für den Zugriff auf das SRAM benutzt. Führen Sie dazu ein Steuersignal ein, dass den Adresszähler um eins erhöht. Auch dieses Steuersignal soll aus dem Steuerautomaten kommen. Jetzt soll der Gesamtablauf für das Echosystem mit dem Lese- und dem Schreibzugriff entworfen werden. Der Zugriff wird mit dem adc_valid Signal gestartet. Die Schreibdaten aus dem Audiomodul sollen auch in einem Register zwischengespeichert werden.

  • Zeichnen Sie ein Timingdiagramm mit allen SRAM Signalen, den Enablesignalen für den Tri-State Treiber und die Lese- und Schreibregister sowie dem Steuersignal für das Hochzählen des Adresszählers. Im Timingdiagramm soll auch das adc_valid Signal dargestellt werden.
  • Erläutern Sie warum alle Timinganforderungen des SRAM erfüllt und ein sicherer Betrieb des Datenbus mit den Tristatetreibern gesichert ist.

Entwerfen Sie nun einen Steuerautomaten mit dem der zeitliche Ablauf realisiert wird.

  • Kopieren Sie das de1_audio Design und benennen Sie es in “de1_sram_echo” um. Kopieren Sie auch die Testbench und passen Sie alle entitynamen an.
  • Fügen Sie alle Signale für das SRAM in den Toplevel ein und passen Sie die Testbench an.
  • Ersetzen Sie das Modul “ringbuf” durch das Modul neue Modul “sram_echo”.
  • Im neuen Modul “sram_echo” soll der Steuerautomat, das Leseregister, das Schreibregister und der Adresszähler sein.
  • Der Tri-State Buffer soll auf dem de1_sram_echo Toplevel beschrieben sein. Das Interface von “sram_echo” darf keine bidirektionalen Ports haben.
  • Zeichnen Sie ein Blockschaltbild mit dem Tri-Statetreiber, dem Schreib- und Leseregister, dem Adressregister, dem Steuerautomaten und dem SRAM. Machen Sie im Blockschaltbild deutlich wo die FPGA Pins sind. Zeichnen Sie auch ein welche Komponenten im Modul “sram_echo” sind.
  • Definieren Sie das Interface vom Modul “sram_echo”.

Für die Verifikation soll in die Testbench ein Modell des externen SRAM eingefügt werden. Skalieren Sie das Echosystem und des SRAM auf kleinere Speicherwerte um eine Simulation in angemessener Zeit zu ermöglichen. Schreiben Sie ein Verhaltensmodell des SRAM und zeigen Sie die Echofunktion im Simulator.

Wenn Sie sicher sind, dass es zu keinem Kurzschluss auf dem bidirektionalen Datenbus kommt, dann probieren Sie das Design auf dem FPGA Board aus.

  • dtpr_sram_echo.txt
  • Last modified: 2021/06/14 10:41
  • by beckmanf