CtLab FPGA SigLab

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Das CtLab FPGA SigLab ist ein FPGA-basierter Signalgenerator für die Spartan-3-FPGA-Karte aus dem c´t-Lab und die dazugehörige DACRAM-Erweiterungskarte (Verweise zu diesem Projekt am Ende dieser Seite). Es kombiniert einen modulierbaren Mehrfach-DDS-Generator, einen Universalzähler für Frequenz- und Periodenmessungen sowie einen Pulsgenerator. Dazu gibt es eine grafische Bedienoberfläche sowie die .NET-Klassenbibliothek CtLab Library.

Technische Merkmale

  • Universalzähler (Frequenz-/Periodenmesser)
    • Frequenz bis ca. 150 MHz, Periodendauer bis ca. 120 Stunden
    • einstellbare Messfrequenz bzw. Torzeit
    • für Pulsgenerator, DDS-Kanal oder externes Signal
    • Anzeige für Überlauf oder ausbleibendes Signal
  • Pulsgenerator
    • getrennt einstellbare Puls- und Pausendauern jeweils von 10 ns bis ca. 40 s
  • 4-kanaliger DDS-Signalgenerator
    • Frequenz bis 50 MHz
    • Rechteck, Sägezahn (steigend oder fallend), Sinus
    • einstellbare Amplitude und Phasenlage, separate Synchronisationsausgänge mit fester Phasenlage 0°
    • jeder Kanal durch die anderen Kanäle in Amplitude, Frequenz und Phase modulierbar (auch gleichzeitig)
    • jeder Kanal auf jeden anderen synchronisierbar
  • Ein- und Ausgänge
    • externer Messeingang des Universalzählers
    • zwei Analogausgänge für frei wählbare Quellen (Pulsgenerator oder DDS-Kanal) gleichzeitig
    • ein Synchronisationsausgang je DDS-Kanal
    • Ausgangs des Pulsgenerators
  • SPI-Slave zur Anbindung an einen Mikrocontroller
    • mehrere addressierbare Register zum Setzen von Konfigurationswerten und Auslesen von Messwerten

Universalzähler (Frequenz-/Periodenmesser)

Dieser Zähler kann entweder die Frequenz eines internen oder externen Signals oder dessen Periodendauer messen. Die Bedienoberfläche errechnet aber auch den jeweils anderen Wert und zeigt beide zusammen an.

Messmethode

Bei der Frequenzmessung dient das zu messende Signal als Takt für den Zähler, ein internes Torsignal steuert die Dauer des Zählvorganges. Bei der Messung der Periodendauer wird der Zähler durch ein internes Signal getaktet, die steigenden Flanken des zu messenden Signals steuern wiederum die Zähldauer. Je nach Messmethode arbeitet der Zähler also in der Taktdomäne des externen Signals oder des Systemtakts, die zu- und abführenden Signale werden entsprechend synchronisiert.

Der interne Zähler selbst wird durch das jeweils genutzte Torsignal weder gestoppt noch zurückgesetzt, er läuft ständig durch. Das Torsignal steuert lediglich das Auslesen des Zählers, der Messwert ergibt sich dann aus der Differenz des aktuellen und des vorangegangenen Auslesewertes. Das funktioniert auch bei einem Zählerüberlauf, solange danach der aktuelle Auslesewert den vorangegengenen nicht einholt. Der nutzbare Zählbereich hängt also nur von der Bitbreite des Zählers ab. Echte Überläufe dieses nutzbaren Bereiches werden erkannt und signalisiert.

Da das Torsignal auf das Taktsignal einsynchronisiert wird, arbeitet die Ausleselogik bei fehlendem externen Signal nicht mehr, weder bei Frequenz- noch bei Periodenmessung. In diesem Fall wird weiterhin der Wert aus dem letzten Messzyklus ausgegeben. Eine Art Herzschlagsignal zeigt jedoch an, ob Messzyklen stattfinden oder nicht.

Messbereiche

Der interne Zähler ist 32 Bit breit. Messbereich und Auflösung ergeben sich theoretisch bei der Frequenzmessung direkt aus der Torzeit, bei der Periodenmessung aus der Zählfrequenz. Natürlich gibt es aber physikalische Grenzen, die theoretischen Obergrenzen für die Frequenzmessung können nicht annähernd erreicht werden. Beim eingesetzten FPGA sind Messungen bis über 150 MHz möglich.

Die tatsächlich unterstützten Messbereiche sind:

  • Frequenz:
    • Torzeit 10 s (Auflösung 0,1 Hz)
    • Torzeit 1 s (Auflösung 1 Hz)
    • Torzeit 0,1 s (Auflösung 10 Hz)
  • Periodendauer:
    • Messfrequenz 10 kHz (max > 119 Stunden, Auflösung 100 μs)
    • Messfrequenz 100 kHz (max > 11,9 Stunden, Auflösung 10 μs)
    • Messfrequenz 1 MHz (max > 71 Minuten, Auflösung 1 μs)
    • Messfrequenz 10 MHz (max > 7 Minuten, Auflösung 100 ns)

Pulsgenerator

Pulssignal, Puls 20 μs, Pause 100 μs

Dieser Generator kann ein Rechtecksignal bereitstellen, bei dem sich die Puls- und Pausendauern unabhängig voneinander jeweils von 10 ns bis 42,9 s einstellen lassen. Die Bedienoberfläche lässt sich derzeit allerdings nur bis 1 s einstellen (das wird noch geändert).

Es existieren mehrere Einstellbereiche:

  • 10 ns bis 1 μs (Auflösung 10 ns)
  • 1 μs bis 1 ms (Auflösung 1 μs)
  • 1 ms bis 1 s (Auflösung 1 ms)

Modulierbarer 4-Kanal-DDS-Generator

Dieser nach dem DDS-Prinzip arbeitende Generator kann vier unabhängige Signale unterschiedlicher Kurvenformen bereitstellen, die sich vielfältig beeinflussen und untereinander auch modulieren lassen.

Signalformen

Lissajous-Figur mit zwei DDS-Kanälen, X-Kanal Sinus 2,5 kHz, Y-Kanal Sinus 10 kHz
Sägezahn 10 kHz
Sinus 10 kHz

Jeder der vier Kanäle kann symmetrische Rechtecksignale, steigende und fallende Sägezahnsignale sowie Sinussignale liefern. Die Rechteck- und Sägezahnsignale werden direkt aus dem aktuellen Wert des jeweiligen Phasenakkumulators ermittelt. Die Werte des Sinussignals werden einer Lookuptabelle entnommen, welche pro Periode 4096 Werte bereitstellt (wobei die Tabelle tatsächlich nur 1024 Werte für die erste Viertelperiode enthält, der Rest wird abgeleitet).

Frequenzbereich

Die internen Phasenakkumulatoren werden mit 100 MHz getaktet und sind 32 Bit breit, somit stehen grundsätzlich Frequenzen bis 50 MHz bei einer Auflösung von 0,023 Hz zur Verfügung. Natürlich lässt sich bei zunehmender Annäherung der Grundfrequenz des erzeugten Signals dessen Kurvenform nur noch ungenau darstellen (siehe dazu auch die Erklärunen zum Abtasttheorem hier im Wiki oder in der Wikipedia). Die nutzbare Bandbreite hängt natürlich auch noch vom eingesetzten DA-Wandler und den Ausgangsverstärkern ab.

Amplitude

Die Amplitude ist vom invertierenden Maximum über Null bis zum nichtinvertierenden Maximum einstellbar. Die Wertauflösung beträgt für alle Signalformen 16 Bit bei maximaler Amplitude.

Phasenlage

Die Phasenlage kann in beide Richtungen um jeweils maximal eine Periode verschoben werden (±2π bzw. 360°). Die Auflösung über den gesamten Bereich von ±2π beträgt intern 32 Bit, die Schnittstelle zur Bedienoberfläche nutzt davon derzeit aber nur 16 Bit. Jeder Kanal besitzt einen separaten Synchronisationsausgang, der ein symmetrisches Rechtecksignal liefert, dessen steigende Flanke immer bei Phasenlage 0° liegt. Außerdem kann jeder Kanal auf jeden anderen synchronisiert werden. Bei Phasenlage 0° der ausgewählten Synchronisationsquelle wird dabei der Phasenakkumulator des synchronisierten Kanals auf 0° gesetzt.

Modulation

Frequenzmodulation, Träger Sinus 1 kHz, Nutzsignal Sinus 100 Hz, Frequenzhub 500 Hz
Amplitudenmodulation, Träger Sinus 10 kHz, Nutzsignal Sinus 1 kHz, Modulation 50%

Jeder Kanal lässt sich durch die anderen Kanäle unabhängig voneinander in Amplitude, Frequenz und Phase modulieren, auch gleichzeitig. Die Modulationstiefe lässt sich über die Amplitude des modulierenden Signals variieren. Die maximale Modulationstiefe umfasst bei Amplitudenmodulation (AM) den gesamten Spannungsumfang, bei Frequenzmodulation (FM) den gesamten Frequenzumfang (±25 MHz) in mehreren Bereichen und bei Phasenmodulation ±1/2 Periode (±π bzw. 180°) ausgehend von der eingestellten Phasenlage. Bei Amplituden- und Frequenzmodulation zeigt die Bedienoberfläche an, wenn es zu einer Übermodulation kommt.

Ein- und Ausgänge

Jeder der beiden Analogausgänge der DACRAM-Erweiterungskarte kann wahlweise eines der vier DDS-Generatorsignale oder das Pulsgeneratorsignal ausgeben. Parallel dazu stehen die Synchronisationssignale aller vier DDS-Kanäle sowie das Signal des Pulsgenerators zur Verfügung. Die maximale Amplitude der Analogausgänge beträgt ±1,25 V (2,5Vss), die anderen Ausgänge haben LVTTL- bzw. LVCMOS33-Pegel.

Auf der DACRAM-Erweiterungskarte sind zwei Bestückungsmöglichkeiten vorgesehen:

  • 2-Kanal-DAC AD5447 mit 21 Megasamples und Verstärker AD8055
  • TxDAC AD9752 (12 Bit) oder AD9754 (14 Bit) mit 125 Megasamples und Verstärker LT1818

Das CtLab FPGA SigLab wurde mit der ersten Variante getestet, auch die Bilder wurden damit gemacht.

Der Eingang des Universalzählers sowie die Analogausgänge sind über die DACRAM-Karte zugänglich. Die zusätzlichen Digitalsignale sind auf folgende Pins geführt:

Bedeutung Pin
Syncsignal DDS 0 P99
Syncsignal DDS 1 P95
Syncsignal DDS 2 P113
Syncsignal DDS 3 P112
Pulsgenerator P97

SPI-Schnittstelle

Über den SPI-Slave kann ein Master (z.B. ein Mikrocontroller wie der ATmega644 auf der FPGA-Karte aus dem c´t-Lab) Konfigurationswerte ans CtLab FPGA SigLab übergeben und Messwerte auslesen. Der SPI-Slave besitzt mehrere Datenregister mit 32 Bit Breite, die über ein separates Adressregister ausgewählt werden können.

Der SPI-Slave hat folgende Signale:

  • MOSI (Master Out -> Slave In): zu schreibende Daten zu CtLab FPGA SigLab
  • MISO (Master In <- Slave Out): gelesene Daten von CtLab FPGA SigLab
  • SCLK (Shift Clock): Schiebetakt
  • SS_Address (Slave Select for Address): Auswahl des Adressenregisters
  • SS_Data (Slave Select for Data): Auswahl des aktuell adressierten Datenregisters

Die beiden SS-Signale sowie SCLK sind im Ruhezustand High, zum Übertragen einer Adresse oder eines Datenwortes zieht der Master (also z.B. der Mikrocontroller) das entsprechende SS-Signal und danach auch SCLK auf Low. Der Master legt ein Datenbit an MOSI an und erzeugt an SCLK eine steigende Flanke. Diese veranlasst den Slave, das Datenbit in sein internes Empfangsschieberegister einzulesen. Das wiederholt sich für die folgenden Bits, wobei die höherwertigen Bits immer zuerst übertragen werden. Sofern gerade ein Datenwort (und keine Adresse) übertragen wird, stellt der Slave gleichzeitig an jeder fallenden SCLK-Flanke (inklusive der ersten) jeweils ein Bit aus seinem Sendesschieberegister an MISO zur Verfügung, das der Master dann an der nächsten steigenden SCLK-Flanke übernehmen kann. Am Ende der Übertragung setzt der Master das SS-Signal wieder auf High.

Bei aktiviertem (also auf Low gezogenem) SS_Address wird das Adressregister angesprochen, bei aktiviertem SS_Data dasjenige Datenregister, das durch das Adressregister angegeben wird.

SPI-Anschlüsse

Für die SPI-Schnittstelle sind derzeit zwei Anschlüsse realisiert, die sich im VHDL-Code einzeln oder zusammen aktivieren lassen. Einer ist für die Ansteuerung durch den internen ATmega644 vorgesehen, der andere ist auf die FPGA-IO-Anschlussleiste geführt und kann von externer Hardware (z.B. einem Raspberry Pi) genutzt werden. Falls beide Anschlüsse aktiviert sind, können sie wahlweise (jedoch nicht parallel) genutzt werden.

Die SPI-Anschlüsse sind wie folgt belegt:

SPI-Signal Interner Anschluss Externer Anschluss
Bezeichnung Pin Bezeichnung Pin Pin auf FPGA-IO-Anschlussleiste
MOSI F_MOSI P63 EXT_MOSI P98 a09
MISO F_MISO P73 EXT_MISO P96 a08
SCLK F_SCK P70 EXT_SCK P93 a07
SS_Address F_RS P68 EXT_RS P87 a05
SS_Data F_DS P69 EXT_DS P90 a06

Falls beide Anschlüsse aktiviert sind, ist es wichtig, dass immer nur ein Anschluss benutzt wird und die Select-Leitungen (x_RS und x_DS) für den jeweils ungenutzten Anschluss inaktiv (also auf High-Pegel) bleiben:

  • Wenn die interne Schnittstelle zum ATmega644 verwendet wird, muss die Beschaltung der externen Schnittstelle sicherstellen, dass EXT_RS und EXT_DS auf High-Pegel bleiben (z.B. durch Pullup-Widerstände).
  • Der ATmega644 auf der FPGA-Karte spricht den SPI-Bus periodisch an, wenn auf dem Bedienpanel eine der Param- oder Value-Anzeigen ausgewählt ist. Daher muss das Panel auf die Dateiauswahlanzeige gestellt werden, wenn der externe SPI-Anschluss verwendet wird.

Durch Anpassung des VHDL-Codes kann die ungenutzte Schnittstelle stillgelegt oder komplett entfernt werden.

SPI-Register

Die SPI-Adressen sind wie folgt belegt:

Adresse Richtung Komponente Bedeutung der Bits Anmerkungen
31..16 15..0
7 Schreiben Quelle für Analogausgänge Ausgänge 0 und 1 Bit 7..4: Ausgang 1, Bit 3..0: Ausgang 0 (jeweils Wert 0..3: entsprechender DDS-Kanal, 4: Pulsgenerator)
2 Lesen Universalzähler Status Bit 1: Überlauf, Bit 0: Signal aktiv
3 Lesen Rohmesswert muss entsprechend Torzeit bzw. Messfrequenz umgerechnet werden
1 Schreiben Konfiguration Bit 10..8: Signalquelle (Wert 0..3: entsprechender DDS-Kanal, 4: Pulsgenerator, 5: externes Signal), Bit 4: Messart (Wert 0: Frequenz, 1: Periode), Bit 3..0: Vorteilermodus (s.u.)
5 Schreiben Pulsgenerator Pausendauer Auflösung 10 ns
6 Schreiben Pulsdauer Auflösung 10 ns
8 Schreiben DDS-Kanal 0 Wellenform & Modulationsquelle siehe separate Tabelle unten
9 Schreiben Phaseninkrement bestimmt direkt die Frequenz, Auflösung 0,023 Hz
10 Schreiben Amplitude Phasenlage Vorzeichenbehaftete Werte
12 Schreiben DDS-Kanal 1 Wellenform & Modulationsquelle siehe Anmerkungen zu DDS-Kanal 0
13 Schreiben Phaseninkrement
14 Schreiben Amplitude Phasenlage
16 Schreiben DDS-Kanal 2 Wellenform & Modulationsquelle
17 Schreiben Phaseninkrement
18 Schreiben Amplitude Phasenlage
20 Schreiben DDS-Kanal 3 Wellenform & Modulationsquelle
21 Schreiben Phaseninkrement
22 Schreiben Amplitude Phasenlage
24 Lesen/Schreiben DSO SRAM: Modus/Status, Adresse, Daten Bit 31..29: Modus/Status, Bit 28..8: Adresse, Bit 7..0: Daten
25 Schreiben Konfiguration Bit 10..8: Signalquelle (Wert 0..3: entsprechender DDS-Kanal, 4: Pulsgenerator, 5: externes Signal, 6: Testdaten)


Wellenform & Modulationsquelle:

Bits Bedeutung Anmerkungen
18..16 Wellenform
12..8 maximale Modulationstiefe für FM
7..6 Synchronisationsquelle Synchronisation unabhängig von der eingestellten Phasenlage der Quelle
5..4 PM-Quelle
3..2 FM-Quelle
1..0 AM-Quelle


Der interne Vorteiler des Universalzählers erzeugt aus dem Systemtakt folgendes Signal:

Modus Frequenz (Periodendauer) vorgesehene Verwendung
0 1 Hz (1 s) Torsignal für Frequenzmessung
1 0,1 Hz (10 s)
2 10 Hz (0,1 s)
4 10 MHz Zählsignal für Periodenmessung
5 1 MHz
6 100 kHz
7 10 kHz

Bedienung

Bedienoberfläche

Die Bedienoberfläche wurde in C# mit Gtk# entwickelt. Sie basiert auf der CtLab Library und kommuniziert mit dem CtLab FPGA SigLab über das textbasierte c´t-Lab-Protokoll.

Über Extras->Einstellungen können die Schnittstelle und der Kanal des c´t-Lab-Busses, über welche die FPGA-Karte angeschlossen ist, eingestellt werden. Zusätzlich zu diesen intervallgesteuerten Abfragen werden die Messwerte aber auch unmittelbar ausgelesen, wenn Einstellungen geändert und somit ans CtLab FPGA SigLab gesendet werden.

Die einzelnen Bereiche der Oberfläche werden nachstehend erklärt.

Universalzähler

Für den Universalzähler kann eines der internen Signale oder ein externes ausgewählt werden. Außerdem kann die Torzeit oder die Messfrequenz eingestellt werden, wobei gleichzeitg zwischen den beiden Messarten Frequenz- und Periodenmessung umgeschaltet wird. Der jeweils andere Wert wird errechnet und ebenfalls angezeigt. Ein Indikator zeigt durch mehr oder weniger regelmäßiges Blinken ein anliegendes Signal und somit laufende Messaktivitäten an, ein zweiter Indikator weist auf einen Überlauf des Messbereiches hin (was aber nur bei sehr langen Periodenmessungen vorkommen kann).

Analogausgänge

Für jeden der beiden Analogausgänge kann eingestellt werden, welches der internen Generatorsignale dort erscheinen soll. Zur Wahl stehen die vier DDS-Kanäle und der Pulsgenerator. Die nicht ausgewählten DDS-Kanäle können natürlich weiterhin zur Modulation anderer Kanäle verwendet werden. Außerdem sind zusätzlich zu den beiden Analogausgängen immer auch noch die Digitalsignale (DDS-Synchronisation, Pulsgenerator) verfügbar.

Pulsgenerator

Hier können die Puls- und Pausenlängen in mehreren Bereichen eingestellt werden. Die sich daraus ergebende Frequenz wird angezeigt.

DDS-Generator

Die Bedienelemente für die vier Kanäle des DDS-Generators sind hier auf zwei Registerkarten untergebracht. Es kann die Wellenform ausgewählt und die Frequenz eingestellt werden.

Die Amplitude kann vom invertierenden Maximum bis zum nichtinvertierenden Maximum eingestellt werden. Damit lässt sich z.B. ein fallendes oder steigendes Sägezahnsignal erzeugen. Die Phasenlage kann um jeweils eine Periode in beide Richtungen verschoben werden. Als Quellen für die Modulationsarten AM, FM und PM können die jeweils anderen drei DDS-Kanäle in beliebiger Kombination ausgewählt werden. Für FM kann die maximale Modulationstiefe in mehreren Stufen ausgewählt werden (die 'krummen' Endwerte ergeben sich durch die wiedeholte Teilung von ±25 MHz durch 8). Bei AM und FM wird eine eventuelle Übermodulation angezeigt.

Hinweise zur Realisierung

Das CtLab FPGA SigLab wurde unter Verwendung von Xilinx ISE 11.1 entwickelt. Im FPGA-Code wurde auf Portabilität geachtet. Alle Bestandteile sind in VHDL implementiert, Schematics werden nicht verwendet. Xilinx-Spezifika wurden fast vollständig vermieden, die interne Taktverdoppelung per DCM ist gekapselt. Der Code sollte sich also relativ leicht auf andere FPGA-Karten und auch auf andere FPGAs übertragen lassen. Durch die Verwendung von Generics im VHDL-Code sind viele Aspekte relativ leicht änderbar (z.B. Wert- und Zeitauflösung der DDS-Generatoren, Größe der DDS-Lookup-Tabellen, Anzahl der Adressen des SPI-Slaves,...). Für nahezu alle Entitäten existieren selbstverifizierende Tests und Konfigurationsdateien für die Kurvenformanzeige im Simulator ISim.

Der auf der FPGA-Karte befindliche Mikrocontroller (ATmega644) vermittelt zwischen dem auf dem FPGA realisierten SPI-Slave einerseits und dem über RS232, USB oder Ethernet angeschlossenen PC andererseits. Die Anbindung des PC erfolgt galvanisch getrennt über den Optobus des c´t-Lab. Für den Mikrocontroller wird (derzeit) die Originalfirmware (Version 2.6) benutzt, sie ist nicht Bestandteil dieses Projektes. Zwischen Mikrocontroller und PC wird ein einfaches textbasiertes Protokoll benutzt, um bestimmte SPI-Register zu beschreiben oder auszulesen. Die Bedienoberfläche nutzt dieses Protokoll.

Die Bedienoberfläche sowie wie die zugrundeliegende CtLab Library wurden mit Mono und MonoDevelop auf Ubuntu 16.04 in C# entwickelt. Die CtLab Library lässt sich ohne Änderungen ebenso unter Windows in Visual Studio laden, übersetzen und ausführen (zuletzt getestet mit Visual Studio 2012 unter Windows 7). Die Gtk#-Ansichten der Oberfläche wurden bisher nicht auf Windows getestet. Auch auf dem Raspberry Pi ist die Software einsetzbar und kann auch direkt dort übersetzt werden.

Es lassen sich natürlich auch Bedienoberflächen in anderen Technologien relativ leicht erstellen. Da die Kommunikation zwischen PC und dem Mikrocontroller der FPGA-Karte textbasiert ist, reicht grundsätzlich bereits ein Terminalprogramm aus, um das CtLab FPGA SigLab anzusteuern.

Wiederverwendbare Komponenten

Das CtLab FPGA SigLab enthält einen SPI-Slave mit mehreren adressierbaren Registern, der auch als eigenständige Komponente in anderen Projekten eingesetzt werden kann.

Was noch fehlt

  • weitere Wellenformen bei den DDS-Generatoren, z.B. Dreieck
  • einstellbarer DC-Anteil bei den DDS-Generatoren
  • gemeinsame Nutzung der Wellenformtabellen für die vier DDS-Generatoren
  • Erweiterung zum Arbiträr- bzw. Bitmustergenerator.

Quellcode, Lizenz

Das CtLab FPGA SigLab ist quelloffen (Open Source) und wird unter der GNU General Public License (GPL) veröffentlicht. Der Quellcode steht auf GitHub zur Verfügung.

Unter "FPGA/FPGA SigGen" befindet sich das Gesamtprojekt, unter den anderen Unterordnern von "FPGA" befinden sich eingebundene Teilprojekte. Die Projektdatei (*.xise) jedes Projektes befindet sich jeweils im Unterordner "Main". Ansteuern lässt sich ein konfiguriertes CtLab FPGA SigLab am einfachsten mit der CtLab Library, wie dies auch die hier vorgestellte Bedienoberfläche macht.

Weitere Informationen

Quellcode:

Das CtLab FPGA SigLab kann gut mit der CtLab Library gesteuert werden. Näheres gibt es unter:

Das CtLab FPGA SigLab basiert auf dem c´t-Lab von Carsten Meyer, c't magazin. Weitere Informationen gibt es hier:

Viele interessante Informationen zu VHDL und FPGAs habe ich der Website von Lothar Miller entnommen. Herzlichen Dank!