Hallo,
ein ATXMega128a4u soll per DMA Daten aus einem Array im RAM an einen
Port herausschieben. Er läuft mit 32 MHz. Allerdings erhalte ich
deutlich weniger als 32 MSps, obwohl die CPU im IDLE-Mode ist. Es sind
ca. 8 MSps. Warum?
Ich dachte, der RAM und IO sind getrennt, so dass je Zyklus eine
Schreib- und gleichzeitig eine Leseoperation ausgeführt werden. Das
Adressincrement sollte ja ohne Buszugriff stattfinden.
Was kann die Ursache für die geringe Geschwindigkeit sein?
Sicher, dass dieser DMA Controller für Blockdatentransfer direkt vom RAM
zum Port ausgelegt ist? Wenn der byteweise getriggert arbeitet und für
jedes Byte erst einmal den Bus beantragt, das Byte aus dem RAM liest,
auf den Port schreibt und dann den Bus wieder freigibt, dann wären 4
Takte pro Byte völlig in Ordnung.
Edit: Mal reingesehen. Der DMA Controller arbeitet offensichtlich mit
getrennten und gepufferten Lese- und Schreiboperationen, also nicht
direkt vom RAM zum Port. Das wären also schon einmal 2 Takte pro Byte
Minimum. Und wenn man mit 1-Byte Bursts arbeitet, dann überträgt er eben
1 Byte pro DMA-Transaktion, wie eben beschrieben.
Stefan Helmert schrieb:> Ich dachte, der RAM und IO sind getrennt, so dass je Zyklus eine> Schreib- und gleichzeitig eine Leseoperation ausgeführt werden.
Was hat das eine mit dem anderen zu tun?
Und warum liest du nicht einfach vorher im Datenblatt nach, wieviele
Takte ein DMA-Transfer braucht?
"A write to SRAM takes one cycle, and a read from
SRAM takes two cycles. For burst read (DMA), new data are available
every cycle." (S. 25,
http://www.atmel.com/Images/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf
)
"Since the data memory is organized as four separate sets of memories,
the different bus masters (CPU, DMA controller
read and DMA controller write, etc.) can access different memory
sections at the same time." (S. 24)
Axel Schwenke schrieb:> Was hat das eine mit dem anderen zu tun?
Frühe DMA Controller waren teilweise so gebaut, dass sie mit den Daten
selbst nichts zu tun hatten, sondern auf dem Datenbus eine direkte
Verbindung zwischen Peripheriedevice und Speicher herstellten. Es also
keine getrennten Lese- und Schreibzyklen gab, da beides in einem
einzigen Zyklus ablief.
Beispiel hierfür ist der antike Intel 8237 im PC, der den
Floppy-Controller bedient, so noch vorhanden. Dieses Prinzip ist aber
etwas aus der Mode gekommen, auch der Z80 DMA arbeitete schon mit
getrennten Zyklen.
Ich habe gerade selber mal die Datenblätter von Atmel überflogen und muß
feststellen, daß sie sich mit Timingangaben beim DMAC sehr zurückhalten.
Die oben zitierte Aussage zum Speicher-Timing ist so ziemlich die
einzige Quelle.
Damit wären je nach Betriebsart (Burstmodus) 1 oder 2 Takte für das
Lesen aus dem SRAM nötig, ein weiterer Takt für das Schreiben [1] und
der anscheinend 4. verbrauchte Takt dann für das Inkrementieren der
Adreßzeiger, Dekrementieren des Blöcklängenzählers und Prüfen der
Abbruchbedingung im DMAC.
[1] Ich gehe nicht davon aus, daß Atmel da einen echten Crossover
zwischen den diversen Busteilnehmern implementiert. Der DMAC wird eher
von einem Busteilnehmer lesen (in ein internes Register) und in einem
zweiten Buszyklus auf einen anderen schreiben.
Stefan Helmert schrieb:> Ja, aber er hat ja einen Buffer (der DMAC). Der sollte doch pipelined> arbeiten und so das nächste Byte lesen, während er das alte rausschiebt.
Weshalb nimmst du das an? Solch ein Verhalten wäre für DMA untypisch.
DMA ist zur Entlastung von Hintergrundtransfers vorgesehen. Nicht für
Blocktransfers mit maximal möglicher Tranferrate.
A. K. schrieb:> Weshalb nimmst du das an?
Naja, weil ich es so konstruieren würde. Mit wenigen % Mehraufwand
könnte damit mehr als die doppelte Leistung erreicht werden.
Aus dem oben erwähnten Maual
> A bus arbiter controls when the DMA controller and the AVR CPU can use the bus.
The CPU always has priority, and so as long as the CPU requests access to the bus,
any pending burst transfer must wait. The CPU requests bus access when it executes
an instruction that writes or reads data to
SRAM, I/O memory, EEPROM or the external bus interface.
Wenn dein Programm sehr viel im SRAM macht, dann kommt der DMA
Controller auch seltener dran. Hast du da eine ungeschickte
Warteschleife implementiert?