Adressierung I/O-Register AVR

Gast #6561211
Lesenswert?

Liebes Forum,

das Speichermodell bei AVR sieht die 64 I/O-Register im linearen 
Speicheradressraum an Adresse 0x0020 bis 0x005F vor, also nach den 32 
General Purpose Regisren an 0x0000 bis 0x001F. Zugriff über Load/Store.

Zusätzlich dazu existieren für die I/O-Register die Adressen 0x0000 bis 
0x001F für das Lesen/Schreiben mit den entsprechenden OpCodes IN/OUT.
Der Zweck ist klar, schnellerer Zugriff durch Einsparung von Taktzyklen.

Die Frage, die sich mir nun stellt: wie wird die Adressierung der 
I/O-Register physisch umgesetzt? Die Register (sowie alle anderen 
Speichergeräte am Datenbus) sind ja über Adressdekoder an den Bus 
angebunden. Wird nach der Verarbeitung von IN/OUT das 0x0020-Offset 
schaltungstechnisch beaufschlagt?
Ein eigener Adressbus in Form von Busleitungen und eigene Adressdekoder 
wird ja nicht existieren.

Besten Dank und schöne Grüße

Bernd
Gast #6561260
Lesenswert?

Bernd schrieb:

> Die Frage, die sich mir nun stellt: wie wird die Adressierung der
> I/O-Register physisch umgesetzt?

Es gibt physisch keinen einheitlichen linearen Adressraum, sondern 
mehrere Busse. Entweder der Opcode stellt bereits klar, auf welchen 
davon zugegriffen werden muss (in, out, sbis, sbic, sbi, cbi, lpm, spm) 
oder der Bereich innerhalb des virtuellen SRAM-Addressraums (alles 
andere) wird entsprechend auf den jeweiligen Bus gemapped, indem 
schlicht der Offset der Basis des Mappings entfernt wird.
Gast #6561330
Lesenswert?

c-hater schrieb:

> Es gibt physisch keinen einheitlichen linearen Adressraum, sondern
> mehrere Busse.

OK, verstehe. Also hängt die I/O-Gruppe an ihren "eigenen" Bus und die 
IN/OUT OpCodes sorgen dafür, dass die Daten auf diesesn Bus gelegt 
werden.

Wird mit LOAD/STORE nun auf 0x0020 zugegriffen, dann erfolgt das 
Entfernen des Offsets und die Adresse wird konsistent mit der von 
IN/OUT. Wie aber implementiert die CPU, dass die Daten jetzt auf den Bus 
für die I/O-Gruppen gelegt werden und nicht zum pysischen SRAM?

Gruß
Bernd
Gast #6561404
Lesenswert?

Bernd schrieb:

> Wie aber implementiert die CPU, dass die Daten jetzt auf den Bus
> für die I/O-Gruppen gelegt werden und nicht zum pysischen SRAM?

Na eben dadurch, dass die Adresse ausgewertet wird. Liegt sie im 
IO-Fenster, wird die Basis des IO-Fensters weggeworfen und der Rest an 
den IO-Bus verfüttert.
#6561410
Lesenswert?

Bernd schrieb:
> OK, verstehe. Also hängt die I/O-Gruppe an ihren "eigenen" Bus

Das Diagramm in den Datasheets legt einen gemeinsamen Bus für Daten und 
I/O nahe. Aber das ist eine sehr schematische Darstellung, die der 
internen Implementierung nicht genau entsprechen muss. Eine nähere 
Beschreibung von Atmel ist mir nicht bekannt.

Von der Oregon State University fand ich unter dem Label ECE375 mal ein 
detailliertes Modell einer Mikroarchitektur der AVRs. Inwieweit da 
Information von Atmel einfloss, oder ob das lediglich ein dort 
entwickeltes Verhaltensmodell ist, weiss ich nicht. War in Kapitel 8. 
Was heute auf deren Webseite ist, hört bei 7 auf.

> IN/OUT OpCodes sorgen dafür, dass die Daten auf diesesn Bus gelegt
> werden.

I/O lässt sich sowohl über IN/OUT/Einzelbit als auch über die diversen 
Load/Store-Befehle adressieren. Diese beiden Befehlsgruppen 
unterscheiden sich funktional nur in einem Offset von 0x20 in der 
Adressierung.

Bei den AVRs sind die Register ebenfalls im Datenadressraum enthalten 
und können über Load/Store angesprochen werden können. Eine Auftrennung 
in eventuelle mehrere Busse kann also nur über die Adresse erfolgen, 
nicht über den Opcode.
Gast #6561421
Lesenswert?

c-hater schrieb:

> Na eben dadurch, dass die Adresse ausgewertet wird. Liegt sie im
> IO-Fenster, wird die Basis des IO-Fensters weggeworfen und der Rest an
> den IO-Bus verfüttert.

Alles klar. Die Auswertung kann ja durch einen Dekoder übernommen 
werden.

Vielen Dank für die Hilfe!
Bernd
Gast #6561444
Lesenswert?

Bernd schrieb:

> Alles klar. Die Auswertung kann ja durch einen Dekoder übernommen
> werden.

Wird sie! Darauf kannst du einen lassen ;o)

Das Konzept ist normal clever. Man könnte ja vielleicht meinen, dass es 
zwei Stufen geben müsste (Fenster erkennen->passenden Bus ansprechen & 
mappen), das ist aber nicht so. Das passiert alles in einem Takt-Schritt 
mit rein bool'scher Logik.
Gast #6562316
Lesenswert?

Leidgeplagter schrieb:
> Ahhhhhh .....
>
> Endlich mal wieder ein Thread wo nicht "mein Arduino lässt
> sich nicht mehr programmieren" steht. Und das Niveau auch
> etwas höher liegt.
>
> Das tut guuuuuuut.

Danke für das Lob!
Die Eingangsfrage drängte sich nach der Lektüre von Andrew S. Tanenbaums 
Buch "Computerarchitektur" auf. Das Kapitel "Die Ebene der digitalen 
Logik" beschreibt ja die Adressdekodierung recht schön und demonstriert 
dies mit Memory Mapped I/O an einem PIO, einem EPROM und einem SRAM. Der 
"Adressraum" ist ja immer "nicht-physisch", der Adressdecoder 
entscheidet, ob er ChipSelect aktiviert oder nicht.

Beim x86 läuft I/O und Speicher scheinbar über zwei identische 
Adressräume auf dem gleichen Bus. Dort erfolgt die Unterscheidung, ob 
I/O oder MEM anhand des MREQ- oder des IOREQ-Signals der CPU.
Moderne Implementierungen verfügen ja über Bus-Controller, die je nach 
Adressfenster den entsprechend spezielisierten Bus ansteuern. So 
zumindest, wie ich das verstanden habe.

Der Übergang zwischen ISA und digitaler Logik ist spannend!
Danke für die Hilfe!

Gruß
Bernd
Gast #6562779
Lesenswert?

Man könnte, wenn nur 1 Adr.Byte im OPcode vorhanden, jeweils die 
untersten 256 Bytes ansprechen (evtl. weitere Pages dafür vorsehen), wie 
das zB beim HC11,12 usw gemacht wird.
Selbst 4 oder 5 Adr.Bits im OPcode könnte man so handhaben.
Der Vorteil dann, man hat überall die gleichen Befehle.
#6562841
Lesenswert?

MCUA schrieb:
> Selbst 4 oder 5 Adr.Bits im OPcode könnte man so handhaben.

Genau das geschieht ja, mit 6 Bits bei IN/OUT. Nur ist die sinnarme 
RAM-Map der CPU-Register r0..r31 an den Datenadressen 0x00..0x1F im Weg, 
daher adressieren IN/OUT die Datenadressen 0x20..0x5F statt 0x00..0x3F.

MCUA schrieb:
> Der Vorteil dann, man hat überall die gleichen Befehle.

68xx verwendet den gleichen Namen LDA für verschiedene Opcodes. AVR 
verwendet verschiedene Namen für verschiedene Opcodes. Das ist alles.
Gast #6562921
Lesenswert?

> Genau das geschieht ja, mit 6 Bits bei IN/OUT
Für diesen (über 6 Bits breit angegeben) Adr-Bereich können aber nur 
diese extrem wenigen Befehle angewandt werden.
Bei 6800, HC11 usw ist das besser.
BefehlsTyp (ADD, LD.., ST.. usw) sind da von Adr.Bereich (meist) 
unabhängig.
#6562942
Lesenswert?

MCUA schrieb:
> Für diesen (über 6 Bits breit angegeben) Adr-Bereich können aber nur
> diese extrem wenigen Befehle angewandt werden.

Willkommen bei RISC. Speicheradressierung gibts eben fast nur in Form 
von Load/Store-Befehlen. Das hat aber nichts mit Adressräumen zu tun. 
Compilern tut das nicht weh - im Gegenteil - und die waren ein Hauptziel 
beim Design.
Gast #6563442
Lesenswert?

MCUA schrieb:
> Dieses AVR-Adress-Schema hat den Nachteil, dass nicht alle Befehle auf
> jeden SpeicherBereich angewandt werden können.

Man könnte es auch anders herum formulieren:

Dieses Adress-Schema hat den Vorteil, dass man auf die wichtigsten 
Register viel schneller zugreifen kann.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren