Re: MIPS32 in VHDL
Posted: Fri Dec 06, 2024 8:35 pm
Zu dem Blockschaltbild -
1.) R-Typ
2.) I-Typ
3.) J-Typ
So weit ich hier sehe, ist kein J-Typ implementiert
1.) R-Typ: Register
2.) I-Typ: Immidiate
3.) J-Typ: Jump Absolut wert im speicher zu dem gesprungen wird
Klassischer Additionsbefehl
1.) Intel: ADD AX, BX
2.) MIPS32: add $r0, $r1, $r2
oder: add $r0, $r0, $r1
Addition:
x = 5 + 4
9 = 5 + 4
c = a + b
1.) zwei Quelloperanten
2.) Ein Zieloperant
Vier Grundrechenarten auf die ganzen und natuerlichen Zahlen
1.) Addition
2.) Subtraktion
3.) Multiplikation
4.) Division
3 Operanten/Operanden! - 2 quell, 1 Ziel
Operantenschreibweise beim Computer
1.) zwei Operanten schreibweise
2.) drei Operanden schreibweise
intel x86/i386/i586/amd64, Atmel Atmega 8: 2 - Einer der Quelloperanten entspricht dem Ziel
MIPS32: 2 Quelloperand, ein Ziel
Kommt auf das gleiche raus
Mikroarchitektur: Implementierung der CPU - egal, etwa: Heimlich kodiert im befehl, bei 2 Operanden, als 3
Oder sie loesen das Intern, sie koennen beliebig Schaltwerke bauen, oder schaltung, die schreibt und laedt, egal
Vorsicht!
Akkumulatorarchitektur
1.) Ein Operanden schreibweise
ausgangspunkt ist der Akku - besonders ausgezeichnetes, Allzweckregister
Akku: Ein Operand, der andere ist immer der Akku
wie kommt das da rein: Datentransferbefehl
vor jeder Arithmetischen Operation immer ein Datentransferbefehl fuer den akku
2.) Stack und Kellerarchitektur - 8087 intel
PUSH r0
PUSH r1
ADD
Kein Operand. nur bei Push und Pop landen auf Stack, Add, die letzten beiden Werte oben auf
Stack, ziel wieder auf Stack
1.) R-Typ typisch arithemtisch
1.) Ein Ziel, zwei quellen - alles Register
r: Register
rs: Quelloperand - r Register, s source
rt: Quelloperand - r Register, t source - man kann schreiben s1, s2, aber das mehr zeichen => s/t
rd: Zieloperand - r Register, d - destination
befehl:
Opcode rs, rt, rd
Befehl: 32 Bit
Opcode: 6 Bit
rs: 5 Bit
rt: 5 Bit
rd: 5 Bit
da, es 32 Bit register gibt, genuegen 5 Bit, um alle Register an zu sprechen, 2^5 = 32
Bit 31 bis Bit 26: OpCode
Bit 25 bis Bit 21: rs
Bit 20 bis Bit 16: rt
Bit 15 bis Bit 11: rd
...
Der Registersatz, hat
1.) Daten
2.) register Select - Entspricht - Addresse im RAM kann 32 Werte annehmen, fuer 32 Register, 2^5
weil, im Befehl: 2 Quellregister, 1 Zielregister ...
Die Werte, mit denen beim MIPS32 gehandelt werden, sind 32 Bit breit ^= 4G
Das sind die Werte selber, auf die Operiert wird, uebliche groessen beim Computer sind
4 Bit - 1 Nibble - absolut selten in der Vergangenheit
8 Bit - 1 Byte - Mikrocontroller
16 Bit - 1 Wort - zum Beispiel x86, erster IBM PC, ohne MMU und speicherschutz, vor Linux, Minix/MS-DOS
32 Bit - 1 Doppelwort - i386, IBM PC nachfolger, mit MMU und Paging, auf das Linus Torvalds Linux gemacht hat, mit Speicherschutz, MMU
64 Bit - amd64 - moderne Computer, intel core i3, i5, ...
Gut, operieren z.B. MIPS32, auf Werte, die 32 Bit breit sind 0 .. 4G -1,
Werte: inhalte
Wo liegen die Werte: Speicherplatz, register
Speicherplatz: Addresse
Register: Registerselect
32 register - heisst, Registerselect 5 Bit - 32 Register im Registersatz ansprechbar 2^5 = 32
Es sind in 32 Register, werte mit 32 bit ansprechbar, die Register selber: Anzahl 32
2^5
rs, rt, rd
jeweils 5 Bit, um jeweils eines der 32 Register aus zu waehlen, die jeweils werte mit 32 bit kodiert enthalten, 0 .. 4G - 1
R-Typ befehl
31 .. 26: Opcode (immer 6 Bit)
25 .. 21: rs (5 Bit)
20 .. 16: rt (5 Bit)
16 .. 11: rd (5 Bit)
11 .. 6:
5 .. 0: func feld
OK - Datenpfad
Prozessor:
1.) Rechenwerk
2.) Leitwerk
komplexes schaltwerk
1.) Operationswerk
2.) Steuerwerk
Einfaches Schaltwerk
1.) Schaltwerk
2.) uebergangsschaltnetz - zum naechsten Zustand
3.) Ausgangsschaltnetz - fuer die Ausgabe
komplexes schaltwerk
1.) Operationswerk: Kann Register enthalten
2.) Steuerwerk
Prozessor:
1.) Rechenwerk: Universelles Operationswerk
2.) Leitwerk: Umschaltbares Steuerwerk
1.) Rechenwerk: Komplexes Schaltwerk: Kann register enthalten
Rechenwerk: ALU + Registersatz
2.) umschaltbares Steuerwerk: holt Befehle aus dem Speicher, Befehle genuegen im gegensatz zu den Eingaben
beim einfachsten Schaltwerk oder Komplexen Schaltwerk, in jedem Fall sehr einheitlichen Definitionen/...
Rechenwerk = universelles Operationswerk
Rechenwerk = ALU + Registersatz
R-Typ befehl: 3 operanden
c = a + b
$r3 = $r1 + $r2
add $r3, $r1, $r2
Datenpfad, Vorsicht:
1.) Datum im Register selber
2.) Auswahl des Register
Macht: 6
1.) Zwei quellregister
2.) ein Ziel register
macht 3
1.) Datum selber, 32 Bit
2.) Register Select, Register Auswahl, 5 Bit
macht 2
2*3 = 6
Jetzt Addition findet auf zwei Quellregister statt und landet im Zielregister
Die Operation findet in der ALU statt
Zwei quellregister aus dem Registersatz werden selektiert und ihre Werte werden in der ALU arithmetisch logisch
verarbeitet verknuepft und landen als Wert im Registersatz naemlich dort im Zielregister, selektiert wie jedes
Register, mit 5 Bit, ankommt, ein 32 Bit Wert
Gut:
Registersatz -> ALU -> Registersatz
Datenpfad, R-Typ
4 x MUX!
MUX gesteuert ueber - Befehlsdekodierer
Ich nenne sie
MUX1,
MUX2,
MUX3,
MUX4
Nummierung: Von west nach ost - links nach rechts
Norden nach sueden, oben nach unten
An Zustandselementen - Register, Speicher - WE
WE - Write enable
WE - Writenable: HIGH, in das Zustandselement wird geschrieben
Jederzeit landen die Daten sowohl an den Eingaengen vom Speicher, ...
... als auch von registern
blos: WE - HIGH - am registersatz, daten uebernehmen
WE - HIGH am speicher, daten im Speicher uebernehmen
dadurch dass z.B. HIGH am Registersatz, LOW am Speicher, WE - Daten im Registersatz uebernehemen, nicht im Speicher
MemWrite: 1 Bit: Befehlsdekoder - Speicher, speicher: WE - heisst, Memory Write
RegWrite: 1 Bit: Befehlsdekoder - Registersatz, we - heisst, Registerset write
so, ob daten, hier und Dort uebernehmen, die am gleichen Datenpfad, ausgang letzte Komponente, WE
ausgang: Entweder datum hi oder hot - MUX
MUX: 1 Bit, Steuerbit s
s = 0, A, Hi
s = 1, B, Hot
Gut: R-Typ
Register-Select ^= Name - lese-Register, Quelloperand
^= Name - Schreiberegister, zieloperand
op rs rt rd sa func
rs: Bit 25 bis Bit 21 geht in Lese-Register-1 Registersatz, Auswahl
rt: Bit 20 bis Bit 16 geht in Lese-Register-2 registersatz, auswahl
laesst
Lese-daten-1 - 32 bit wert aktiv werden, sind sie so oder so, werden selektiert
Lese-Daten-2 - 32 Bit wert aktiv werden, sind sie so oder so
Jetzt kommt MUX2, MUX2: ALUSrc
Hi und Hot
0: Hi: Operand 2 - ist Lese-Daten-2 ALU, 2. Quelloperand
add $r0, $r1, $r4
indem Falle $r4
ALU-Src
src: Quelle
ALU-src- Quelle des 2. ALU Quelloperanden, 1. immer aus Registersatz, Lese-Daten-1
ALU-src: MUX, Selektion: Entweder aus Registersatz, vor der ALU, ALU, Src, woher, Quelle, bei ALU
1. Operand, immer Registersatz, zweiter: I-Typ Befehl
Gut: R-Typ:
Jetzt Ergebnis an ALU, MUX 3.
Moegliche Alternative:
Store
Load/Store
I-Typ
I-Typ braucht 2 Register, nicht wie gemeint, 1 und eine Addresse
wird gleich erklaert
Die Daten der ALU, Zieloperand, gehen gleichzeitig
1.) In den Datenspeicher
2.) MUX3
Da nicht in Datenspeicher, WE von Datenspeicher = 0, daten nicht im Datenspeicher uebernommen
MUX3: hi, MemToReg
MemToReg: Heisst: Memory 2 Register, als from Memory to register?
1.) I-Typ: Speichern
2.) I-Typ: Laden
oder
1.) I-Typ: Speichern
2.) I-Typ: Laden
3.) I-Typ: Add Immidiate
I-Typ, nachher, aber, waehrend einer I-Typ, Speichern, muss bei Speichern Addresse,
dann waere WE enable = 1, von Speicher
2. I-Typ lesen von speicher, aber jetzt MUX3, = 1, hot, jetzt lesedaten vom Speicher
nach MUX3, in schreibedaten, WE von Registersatz = 1, von Befehlsdekodierer u.
schreiberegister, register select von zieloperand, rd - 3. operand
Aber Vorsicht MUX 1, es kaeme zu kollision
bei i-typ 2 Register, Befehl
wenn sie 3 Register haben, 5 bit Select
5 Bit + 5 Bit + 5 Bit
brauchen sie 5 Bit mehr, als bei 2 Registern select
5 Bit + 5 bit
31 .. 26: opcode
25 .. 21: rs
20 .. 16: rt
15 .. 11: rd
..
bei 3
31 .. 26: opcode
25 .. 21: rs
20 .. 16: rt
15 .. 0: immidiate: 16 Bit konstante aber kein register
..
Deswegen steht der letzte Operand bei R-Typ, das Ziel bei 15 .. 11, bei I-Typ, bei 20 .. 16
hier MUX1, entweder 20:16 oder 15 .. 11 fuer zieloperand, gesteuert ueber: RegDst - Registerdestination, Befehlsdekodierer
R-typ: opcode rs rt rd sa func
I-Typ: opcode rs rt immidiate
immidiate, 16 bit
beim ersteren
i-typ:
zwei Register, Ziel und Quelle und ein 16 Bit direktwert
Im Gegensatz zu einem j-Typ, gibt es keinen 32 - 6 = 26 Bit Direkten wert
Dieser wert ist ausser bei absoluten sprungzielen unbequem, weil wir mit 32 bit rechnen, auch noch
16 bit werte haben. Der nur bei absoluten werten
so. I-Typ: 16 Bit breiter immidiate Wert
16 Bit = 32k Werte.
Dieser ist zweier Komplement, zweier komplement = 1 Komplement +1
einer komplement
1010 = 0101
zweier komplement
0101 +1 = 0110
Oder positive ganzzahl, wenn Vorzeichen gesetzt, dann 2er Komplement
wenn nicht 15 bit positive Ganzzahl, natuerliche
warum Vorzeichenerweiterungseinheit?
weil 16 Bit, aber nachher 32
Wenn man 2er komplement hat, so oder so und/oder natuerliche, 16 Bit
man muss aufpassen bei fuellen oben MSB... zu 32 bit
I-Typ: Speichern, "schreiben" - store
16 Bit immidiate von Befehl
31 .. 26: Opcode
25 .. 21: rs
21 .. 16: rt
15 .. 0: immidiate
15 .. 0 immidiate geht durch vorzeichenerweiterungseinheit, wird 32 Bit
jetzt kommt MUX2, ALU-Src, dies Mal, von Vorzeichenerweiterungseinheit, nicht Registersatz, Op2
wird mit operand1, addiert
das ist Addressierung: Register mit festen relativem wert
Register + Fester Relativer Wert
Operand 1, register satz, wie immer geht, in ALU, muss + immidiate
Geht zusammen Addition in ALU, Zieloperand, dies Mal addresse vom Arbeitsspeicher, datenspeicher, Heap, bildet Addresse
jetzt WE Write enable von Datenspeicher = 1, in Datenspeicher wird geschrieben, blos what?
Register 2 - operand 2, direkt rein.
Store - Addresse im RAM und Register, fertig
Die Addresse im RAM aus immdiate und Register, 2, damit Ende
Rest regelt sich, dass WE bei registersatz nicht aktiv, auch, wenn daten dahin
Load: wie gerade eben.
Hier zwei Moeglichkeiten, gaebe es:
Wie bei R-Typ addiere ich beide quellregister, und tue sie in die ALU, und sie bilden addresse
Addresse vom RAM, immer von ALU-Ergbnis Operand 3
Oder wie gerade eben, store
immdiate
immdiate durch vorzeichenerweiterungseinheit
MUX2 = 1
--> Immidiate + lese-daten 1, registersatz, Addresse,
aber, WE am RAM = 0.
Dafuer MemToReg, MUX3, = 1. Bedeutet, jetzt nicht ALU-Ergebnis in registersatz, sondern RAM und jetzt wie gehabt, wie vorher
Was die Spruenge und Befehle im Programmspeicher betrifft
Vorsicht!
neumann: daten und Programmspeicher gemeinsam
Harvard: Gemeinsam
Atmega8: Harvard: SRAM und Programmspeicher
Programmspeicher nicht fluechtig
Ganz anderer Pfad, Spruenge
Auch Immdiate
Aber das zeigt nich in den Datenspeicher
Programmablauf:
Befehl, Befehl, Befehl, ...
Da Befehl, 32 Bit
Speicher 4 bit, immer +4, +4, +4, Programmzaehler
Befehlszaehler -> Addierer 1, +4
jetzt MUX4,
MUX4, ist Branch
Wozu? normaler Befehl +4, +4, ...
Ich muss wissen, will ich verzweigen oder weiter gerade aus.
Wegen Bedingten Spruengen?
Nein Generell. Unabhaengig, ob bedingt oder nicht
Bei verzweigungen und Spruengen liegt die Addresse nicht an der naechsten stelle.
Sie steht im Befehl. bei normalen Befehlen nicht, immr +4
Deswegen MUX4: Befehlsdekodierer, Branch
Hueh: 0: +4
Hot: Vorzeichenerweiterungseinheit, - immdiate, positiv negativ zu 32 Bit
Dann um 2 nach links
warum? Bei direktwerten nicht, im Befehl, Addition, aber befehl kann nicht an Stelle
n+1, n+2, n+3 liegen, weil Befehl immer 4 byte, also shift nach links
Dann geht das in addierer 2. Warum?
Zunaechst spruenge sind relativ. Das heisst, zum aktuellen Befehlszaehler, aber das ist irrefuehrend
Da der naechste Befehl ohne Sprung, +4, +4, +4
geht es immer durch addierer 1. +4
jetzt koennte man die Verzweigung zum aktuell letzten Befehlszaehler addieren, in Addierer 2
Tatsaechlich geht der PC immer durch Addierer 1, +4 und jetzt relativ
immdiate geht durch vorzeichenerweiterung, 16 nach 32 Bit, dann << 2 nach links, wegen 4 Byte Grenze,
dann addierer, relativ dazu addieren, aber zu addierer 1 +4, fertig
jetzt kommt MUX4, und macht die verzweigung
Befehle
lb
lbu
lh
lhu
lw
ld*
la*
li*
sb
sh
sw
sd*
add
addi
addiu
sub
mult
multu
div
divu
and
andi
or
ori
xor
xori
Verzweigungen:
breq, brne
blt, ble
bgt, bge
beqe*, bnez*
bgtz, bgez
bltz, blez
das eine mit entspricht null, das andere vergleich Register, Register
Zu gegebener Massen, war da ein Fehler drin, den jeder Intel Programmierer kennt
2^16 = 64k
Jedes Intel Segment ist 64k. das weiss, jeder, das liegt daran, der fehler, dass ich die 2er Potenzen bis 8192 auswendig kenne
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192
und jetzt wird es spannend, folgen sie meinen Uebungen, Binaerzahlen um zu rechnen, rechne ich bei Bit 14 und Bit 15 immer
8192*2
8192*4
seltsam, 8192 ist Bit 13
Und 16384 Das weiss ich noch auswendig 14
ebenso wie 32k bit 15
32k bit 15, ist Bit 15, 32k, warum dann 64k
weil 64 k ist
1111 1111 1111 1111
32 k:
1000 0000 0000 0000
rechnet man
0111 1111 1111 1111
kommt man auf 32k-1, zusammen mit der 0, 32k
0111 1111 1111 1111
kommt man auf 2x32k = 64k
Das ist in der Eile passiert, tut mir leid, jeder Intel Programmer weiss, die Segmente sind 64k
Das ist nicht so besonders spannend, meine Erklaerungen zum MIPS32, sind gut und absolut richtig
Ansonsten muss man sich nur noch merken
1.) Der Opcode ist immer 6 Bit breit - also das, was entscheidet, welcher Befehl kommt, im 32 Bit Befehl
2.) Es gibt: Befehlsdekodierer
3.) Es gibt: Funktionsdekodierer
Der Befehlsdekodierer ist fuer das Grobe ausserhalb der ALU zustaendig, WE an Speicher und Registersatz
Der Funktionsdekodierer wird von dem Befehsldekodierer mit gesteuert
Man koennte ihn wohl auch gleich im befehlsdekodierer unterbringen
Er steuert die ALU feiner
1.) Es gibt eine Grobe Steuerung fuer das wichtigste
2.) eine feine Steuerung, fuer das besondere
1.) Der Befehlsdekodierer erkennt einen befehl fuer die ALU - R-Typ, 2 Operanden, arithmetisch/logisch
2.) Das teilt er dem Funktionsdekodierer mit, und 2 mit 2 Bit
00 - addition
01 - subtraktion
10 - nutze das func-feld
11 - n/a
na: not applicable/not accessable = nicht machbar = unsinn
nc: not connected, an bauteilen
Der R-Typ Befehl
31 .. 26: opcode
25 .. 21: rs
20 .. 16: rt
15 .. 11: rd
10 .. 6: sa
6 .. 0: func
func: Im Befehl genaue Steuerung fuer den Funktionsdekodierer
Zwischen Befehlsdekodierer und Funktionsdekodierer 2 Bit
00 - immer Addition - Addition, das groebste, essentiell, rudimentaer
01 - subtration ebenso
Aber Arithmetisch logisch:
Addition, Subtraktion, multiplaktion, division
AND, OR, XOR, NOT, NOR
SHIFT RIGHT, LEFT, ROTATE RIGHT, LEFT
...
Deswegen:
10 - an Befehlsdekodierer: func feld
Das geht so:
100 000 - add - dieser ist redudant - 00 beudetet immer add, zwischen (1) und (2) 10 nutze func feld, hier noch mal add
100 010 - sub
100 100 - and
100 101 - or
101 010 - slt
100 000 - 4 0
100 010 - 4 2
100 100 - 4 4
100 101 - 4 5
101 011 - 5 2
Das kann man sich nicht merken. Also wer linux kann, kann sich rechte merken
rwx
111 - rwx
110 - rw
101 - rx
100 - r
011 - wx
010 - w
001 - x
000 - nichts
da kann man sich 4 0, 4 2... noch merken
vom Funktionskekodier an ALU
001 add
110 sub
000 and
001 or
111 slt
das ist vom Funktionsdekodier an ALU
Das andere func Feld im Befehl
und 2 Bit Befehlsdekodierer Funktionsdekodier
und 5 Bit Opcode
1.) R-Typ
2.) I-Typ
3.) J-Typ
So weit ich hier sehe, ist kein J-Typ implementiert
1.) R-Typ: Register
2.) I-Typ: Immidiate
3.) J-Typ: Jump Absolut wert im speicher zu dem gesprungen wird
Klassischer Additionsbefehl
1.) Intel: ADD AX, BX
2.) MIPS32: add $r0, $r1, $r2
oder: add $r0, $r0, $r1
Addition:
x = 5 + 4
9 = 5 + 4
c = a + b
1.) zwei Quelloperanten
2.) Ein Zieloperant
Vier Grundrechenarten auf die ganzen und natuerlichen Zahlen
1.) Addition
2.) Subtraktion
3.) Multiplikation
4.) Division
3 Operanten/Operanden! - 2 quell, 1 Ziel
Operantenschreibweise beim Computer
1.) zwei Operanten schreibweise
2.) drei Operanden schreibweise
intel x86/i386/i586/amd64, Atmel Atmega 8: 2 - Einer der Quelloperanten entspricht dem Ziel
MIPS32: 2 Quelloperand, ein Ziel
Kommt auf das gleiche raus
Mikroarchitektur: Implementierung der CPU - egal, etwa: Heimlich kodiert im befehl, bei 2 Operanden, als 3
Oder sie loesen das Intern, sie koennen beliebig Schaltwerke bauen, oder schaltung, die schreibt und laedt, egal
Vorsicht!
Akkumulatorarchitektur
1.) Ein Operanden schreibweise
ausgangspunkt ist der Akku - besonders ausgezeichnetes, Allzweckregister
Akku: Ein Operand, der andere ist immer der Akku
wie kommt das da rein: Datentransferbefehl
vor jeder Arithmetischen Operation immer ein Datentransferbefehl fuer den akku
2.) Stack und Kellerarchitektur - 8087 intel
PUSH r0
PUSH r1
ADD
Kein Operand. nur bei Push und Pop landen auf Stack, Add, die letzten beiden Werte oben auf
Stack, ziel wieder auf Stack
1.) R-Typ typisch arithemtisch
1.) Ein Ziel, zwei quellen - alles Register
r: Register
rs: Quelloperand - r Register, s source
rt: Quelloperand - r Register, t source - man kann schreiben s1, s2, aber das mehr zeichen => s/t
rd: Zieloperand - r Register, d - destination
befehl:
Opcode rs, rt, rd
Befehl: 32 Bit
Opcode: 6 Bit
rs: 5 Bit
rt: 5 Bit
rd: 5 Bit
da, es 32 Bit register gibt, genuegen 5 Bit, um alle Register an zu sprechen, 2^5 = 32
Bit 31 bis Bit 26: OpCode
Bit 25 bis Bit 21: rs
Bit 20 bis Bit 16: rt
Bit 15 bis Bit 11: rd
...
Der Registersatz, hat
1.) Daten
2.) register Select - Entspricht - Addresse im RAM kann 32 Werte annehmen, fuer 32 Register, 2^5
weil, im Befehl: 2 Quellregister, 1 Zielregister ...
Die Werte, mit denen beim MIPS32 gehandelt werden, sind 32 Bit breit ^= 4G
Das sind die Werte selber, auf die Operiert wird, uebliche groessen beim Computer sind
4 Bit - 1 Nibble - absolut selten in der Vergangenheit
8 Bit - 1 Byte - Mikrocontroller
16 Bit - 1 Wort - zum Beispiel x86, erster IBM PC, ohne MMU und speicherschutz, vor Linux, Minix/MS-DOS
32 Bit - 1 Doppelwort - i386, IBM PC nachfolger, mit MMU und Paging, auf das Linus Torvalds Linux gemacht hat, mit Speicherschutz, MMU
64 Bit - amd64 - moderne Computer, intel core i3, i5, ...
Gut, operieren z.B. MIPS32, auf Werte, die 32 Bit breit sind 0 .. 4G -1,
Werte: inhalte
Wo liegen die Werte: Speicherplatz, register
Speicherplatz: Addresse
Register: Registerselect
32 register - heisst, Registerselect 5 Bit - 32 Register im Registersatz ansprechbar 2^5 = 32
Es sind in 32 Register, werte mit 32 bit ansprechbar, die Register selber: Anzahl 32
2^5
rs, rt, rd
jeweils 5 Bit, um jeweils eines der 32 Register aus zu waehlen, die jeweils werte mit 32 bit kodiert enthalten, 0 .. 4G - 1
R-Typ befehl
31 .. 26: Opcode (immer 6 Bit)
25 .. 21: rs (5 Bit)
20 .. 16: rt (5 Bit)
16 .. 11: rd (5 Bit)
11 .. 6:
5 .. 0: func feld
OK - Datenpfad
Prozessor:
1.) Rechenwerk
2.) Leitwerk
komplexes schaltwerk
1.) Operationswerk
2.) Steuerwerk
Einfaches Schaltwerk
1.) Schaltwerk
2.) uebergangsschaltnetz - zum naechsten Zustand
3.) Ausgangsschaltnetz - fuer die Ausgabe
komplexes schaltwerk
1.) Operationswerk: Kann Register enthalten
2.) Steuerwerk
Prozessor:
1.) Rechenwerk: Universelles Operationswerk
2.) Leitwerk: Umschaltbares Steuerwerk
1.) Rechenwerk: Komplexes Schaltwerk: Kann register enthalten
Rechenwerk: ALU + Registersatz
2.) umschaltbares Steuerwerk: holt Befehle aus dem Speicher, Befehle genuegen im gegensatz zu den Eingaben
beim einfachsten Schaltwerk oder Komplexen Schaltwerk, in jedem Fall sehr einheitlichen Definitionen/...
Rechenwerk = universelles Operationswerk
Rechenwerk = ALU + Registersatz
R-Typ befehl: 3 operanden
c = a + b
$r3 = $r1 + $r2
add $r3, $r1, $r2
Datenpfad, Vorsicht:
1.) Datum im Register selber
2.) Auswahl des Register
Macht: 6
1.) Zwei quellregister
2.) ein Ziel register
macht 3
1.) Datum selber, 32 Bit
2.) Register Select, Register Auswahl, 5 Bit
macht 2
2*3 = 6
Jetzt Addition findet auf zwei Quellregister statt und landet im Zielregister
Die Operation findet in der ALU statt
Zwei quellregister aus dem Registersatz werden selektiert und ihre Werte werden in der ALU arithmetisch logisch
verarbeitet verknuepft und landen als Wert im Registersatz naemlich dort im Zielregister, selektiert wie jedes
Register, mit 5 Bit, ankommt, ein 32 Bit Wert
Gut:
Registersatz -> ALU -> Registersatz
Datenpfad, R-Typ
4 x MUX!
MUX gesteuert ueber - Befehlsdekodierer
Ich nenne sie
MUX1,
MUX2,
MUX3,
MUX4
Nummierung: Von west nach ost - links nach rechts
Norden nach sueden, oben nach unten
An Zustandselementen - Register, Speicher - WE
WE - Write enable
WE - Writenable: HIGH, in das Zustandselement wird geschrieben
Jederzeit landen die Daten sowohl an den Eingaengen vom Speicher, ...
... als auch von registern
blos: WE - HIGH - am registersatz, daten uebernehmen
WE - HIGH am speicher, daten im Speicher uebernehmen
dadurch dass z.B. HIGH am Registersatz, LOW am Speicher, WE - Daten im Registersatz uebernehemen, nicht im Speicher
MemWrite: 1 Bit: Befehlsdekoder - Speicher, speicher: WE - heisst, Memory Write
RegWrite: 1 Bit: Befehlsdekoder - Registersatz, we - heisst, Registerset write
so, ob daten, hier und Dort uebernehmen, die am gleichen Datenpfad, ausgang letzte Komponente, WE
ausgang: Entweder datum hi oder hot - MUX
MUX: 1 Bit, Steuerbit s
s = 0, A, Hi
s = 1, B, Hot
Gut: R-Typ
Register-Select ^= Name - lese-Register, Quelloperand
^= Name - Schreiberegister, zieloperand
op rs rt rd sa func
rs: Bit 25 bis Bit 21 geht in Lese-Register-1 Registersatz, Auswahl
rt: Bit 20 bis Bit 16 geht in Lese-Register-2 registersatz, auswahl
laesst
Lese-daten-1 - 32 bit wert aktiv werden, sind sie so oder so, werden selektiert
Lese-Daten-2 - 32 Bit wert aktiv werden, sind sie so oder so
Jetzt kommt MUX2, MUX2: ALUSrc
Hi und Hot
0: Hi: Operand 2 - ist Lese-Daten-2 ALU, 2. Quelloperand
add $r0, $r1, $r4
indem Falle $r4
ALU-Src
src: Quelle
ALU-src- Quelle des 2. ALU Quelloperanden, 1. immer aus Registersatz, Lese-Daten-1
ALU-src: MUX, Selektion: Entweder aus Registersatz, vor der ALU, ALU, Src, woher, Quelle, bei ALU
1. Operand, immer Registersatz, zweiter: I-Typ Befehl
Gut: R-Typ:
Jetzt Ergebnis an ALU, MUX 3.
Moegliche Alternative:
Store
Load/Store
I-Typ
I-Typ braucht 2 Register, nicht wie gemeint, 1 und eine Addresse
wird gleich erklaert
Die Daten der ALU, Zieloperand, gehen gleichzeitig
1.) In den Datenspeicher
2.) MUX3
Da nicht in Datenspeicher, WE von Datenspeicher = 0, daten nicht im Datenspeicher uebernommen
MUX3: hi, MemToReg
MemToReg: Heisst: Memory 2 Register, als from Memory to register?
1.) I-Typ: Speichern
2.) I-Typ: Laden
oder
1.) I-Typ: Speichern
2.) I-Typ: Laden
3.) I-Typ: Add Immidiate
I-Typ, nachher, aber, waehrend einer I-Typ, Speichern, muss bei Speichern Addresse,
dann waere WE enable = 1, von Speicher
2. I-Typ lesen von speicher, aber jetzt MUX3, = 1, hot, jetzt lesedaten vom Speicher
nach MUX3, in schreibedaten, WE von Registersatz = 1, von Befehlsdekodierer u.
schreiberegister, register select von zieloperand, rd - 3. operand
Aber Vorsicht MUX 1, es kaeme zu kollision
bei i-typ 2 Register, Befehl
wenn sie 3 Register haben, 5 bit Select
5 Bit + 5 Bit + 5 Bit
brauchen sie 5 Bit mehr, als bei 2 Registern select
5 Bit + 5 bit
31 .. 26: opcode
25 .. 21: rs
20 .. 16: rt
15 .. 11: rd
..
bei 3
31 .. 26: opcode
25 .. 21: rs
20 .. 16: rt
15 .. 0: immidiate: 16 Bit konstante aber kein register
..
Deswegen steht der letzte Operand bei R-Typ, das Ziel bei 15 .. 11, bei I-Typ, bei 20 .. 16
hier MUX1, entweder 20:16 oder 15 .. 11 fuer zieloperand, gesteuert ueber: RegDst - Registerdestination, Befehlsdekodierer
R-typ: opcode rs rt rd sa func
I-Typ: opcode rs rt immidiate
immidiate, 16 bit
beim ersteren
i-typ:
zwei Register, Ziel und Quelle und ein 16 Bit direktwert
Im Gegensatz zu einem j-Typ, gibt es keinen 32 - 6 = 26 Bit Direkten wert
Dieser wert ist ausser bei absoluten sprungzielen unbequem, weil wir mit 32 bit rechnen, auch noch
16 bit werte haben. Der nur bei absoluten werten
so. I-Typ: 16 Bit breiter immidiate Wert
16 Bit = 32k Werte.
Dieser ist zweier Komplement, zweier komplement = 1 Komplement +1
einer komplement
1010 = 0101
zweier komplement
0101 +1 = 0110
Oder positive ganzzahl, wenn Vorzeichen gesetzt, dann 2er Komplement
wenn nicht 15 bit positive Ganzzahl, natuerliche
warum Vorzeichenerweiterungseinheit?
weil 16 Bit, aber nachher 32
Wenn man 2er komplement hat, so oder so und/oder natuerliche, 16 Bit
man muss aufpassen bei fuellen oben MSB... zu 32 bit
I-Typ: Speichern, "schreiben" - store
16 Bit immidiate von Befehl
31 .. 26: Opcode
25 .. 21: rs
21 .. 16: rt
15 .. 0: immidiate
15 .. 0 immidiate geht durch vorzeichenerweiterungseinheit, wird 32 Bit
jetzt kommt MUX2, ALU-Src, dies Mal, von Vorzeichenerweiterungseinheit, nicht Registersatz, Op2
wird mit operand1, addiert
das ist Addressierung: Register mit festen relativem wert
Register + Fester Relativer Wert
Operand 1, register satz, wie immer geht, in ALU, muss + immidiate
Geht zusammen Addition in ALU, Zieloperand, dies Mal addresse vom Arbeitsspeicher, datenspeicher, Heap, bildet Addresse
jetzt WE Write enable von Datenspeicher = 1, in Datenspeicher wird geschrieben, blos what?
Register 2 - operand 2, direkt rein.
Store - Addresse im RAM und Register, fertig
Die Addresse im RAM aus immdiate und Register, 2, damit Ende
Rest regelt sich, dass WE bei registersatz nicht aktiv, auch, wenn daten dahin
Load: wie gerade eben.
Hier zwei Moeglichkeiten, gaebe es:
Wie bei R-Typ addiere ich beide quellregister, und tue sie in die ALU, und sie bilden addresse
Addresse vom RAM, immer von ALU-Ergbnis Operand 3
Oder wie gerade eben, store
immdiate
immdiate durch vorzeichenerweiterungseinheit
MUX2 = 1
--> Immidiate + lese-daten 1, registersatz, Addresse,
aber, WE am RAM = 0.
Dafuer MemToReg, MUX3, = 1. Bedeutet, jetzt nicht ALU-Ergebnis in registersatz, sondern RAM und jetzt wie gehabt, wie vorher
Was die Spruenge und Befehle im Programmspeicher betrifft
Vorsicht!
neumann: daten und Programmspeicher gemeinsam
Harvard: Gemeinsam
Atmega8: Harvard: SRAM und Programmspeicher
Programmspeicher nicht fluechtig
Ganz anderer Pfad, Spruenge
Auch Immdiate
Aber das zeigt nich in den Datenspeicher
Programmablauf:
Befehl, Befehl, Befehl, ...
Da Befehl, 32 Bit
Speicher 4 bit, immer +4, +4, +4, Programmzaehler
Befehlszaehler -> Addierer 1, +4
jetzt MUX4,
MUX4, ist Branch
Wozu? normaler Befehl +4, +4, ...
Ich muss wissen, will ich verzweigen oder weiter gerade aus.
Wegen Bedingten Spruengen?
Nein Generell. Unabhaengig, ob bedingt oder nicht
Bei verzweigungen und Spruengen liegt die Addresse nicht an der naechsten stelle.
Sie steht im Befehl. bei normalen Befehlen nicht, immr +4
Deswegen MUX4: Befehlsdekodierer, Branch
Hueh: 0: +4
Hot: Vorzeichenerweiterungseinheit, - immdiate, positiv negativ zu 32 Bit
Dann um 2 nach links
warum? Bei direktwerten nicht, im Befehl, Addition, aber befehl kann nicht an Stelle
n+1, n+2, n+3 liegen, weil Befehl immer 4 byte, also shift nach links
Dann geht das in addierer 2. Warum?
Zunaechst spruenge sind relativ. Das heisst, zum aktuellen Befehlszaehler, aber das ist irrefuehrend
Da der naechste Befehl ohne Sprung, +4, +4, +4
geht es immer durch addierer 1. +4
jetzt koennte man die Verzweigung zum aktuell letzten Befehlszaehler addieren, in Addierer 2
Tatsaechlich geht der PC immer durch Addierer 1, +4 und jetzt relativ
immdiate geht durch vorzeichenerweiterung, 16 nach 32 Bit, dann << 2 nach links, wegen 4 Byte Grenze,
dann addierer, relativ dazu addieren, aber zu addierer 1 +4, fertig
jetzt kommt MUX4, und macht die verzweigung
Befehle
lb
lbu
lh
lhu
lw
ld*
la*
li*
sb
sh
sw
sd*
add
addi
addiu
sub
mult
multu
div
divu
and
andi
or
ori
xor
xori
Verzweigungen:
breq, brne
blt, ble
bgt, bge
beqe*, bnez*
bgtz, bgez
bltz, blez
das eine mit entspricht null, das andere vergleich Register, Register
Zu gegebener Massen, war da ein Fehler drin, den jeder Intel Programmierer kennt
2^16 = 64k
Jedes Intel Segment ist 64k. das weiss, jeder, das liegt daran, der fehler, dass ich die 2er Potenzen bis 8192 auswendig kenne
1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192
und jetzt wird es spannend, folgen sie meinen Uebungen, Binaerzahlen um zu rechnen, rechne ich bei Bit 14 und Bit 15 immer
8192*2
8192*4
seltsam, 8192 ist Bit 13
Und 16384 Das weiss ich noch auswendig 14
ebenso wie 32k bit 15
32k bit 15, ist Bit 15, 32k, warum dann 64k
weil 64 k ist
1111 1111 1111 1111
32 k:
1000 0000 0000 0000
rechnet man
0111 1111 1111 1111
kommt man auf 32k-1, zusammen mit der 0, 32k
0111 1111 1111 1111
kommt man auf 2x32k = 64k
Das ist in der Eile passiert, tut mir leid, jeder Intel Programmer weiss, die Segmente sind 64k
Das ist nicht so besonders spannend, meine Erklaerungen zum MIPS32, sind gut und absolut richtig
Ansonsten muss man sich nur noch merken
1.) Der Opcode ist immer 6 Bit breit - also das, was entscheidet, welcher Befehl kommt, im 32 Bit Befehl
2.) Es gibt: Befehlsdekodierer
3.) Es gibt: Funktionsdekodierer
Der Befehlsdekodierer ist fuer das Grobe ausserhalb der ALU zustaendig, WE an Speicher und Registersatz
Der Funktionsdekodierer wird von dem Befehsldekodierer mit gesteuert
Man koennte ihn wohl auch gleich im befehlsdekodierer unterbringen
Er steuert die ALU feiner
1.) Es gibt eine Grobe Steuerung fuer das wichtigste
2.) eine feine Steuerung, fuer das besondere
1.) Der Befehlsdekodierer erkennt einen befehl fuer die ALU - R-Typ, 2 Operanden, arithmetisch/logisch
2.) Das teilt er dem Funktionsdekodierer mit, und 2 mit 2 Bit
00 - addition
01 - subtraktion
10 - nutze das func-feld
11 - n/a
na: not applicable/not accessable = nicht machbar = unsinn
nc: not connected, an bauteilen
Der R-Typ Befehl
31 .. 26: opcode
25 .. 21: rs
20 .. 16: rt
15 .. 11: rd
10 .. 6: sa
6 .. 0: func
func: Im Befehl genaue Steuerung fuer den Funktionsdekodierer
Zwischen Befehlsdekodierer und Funktionsdekodierer 2 Bit
00 - immer Addition - Addition, das groebste, essentiell, rudimentaer
01 - subtration ebenso
Aber Arithmetisch logisch:
Addition, Subtraktion, multiplaktion, division
AND, OR, XOR, NOT, NOR
SHIFT RIGHT, LEFT, ROTATE RIGHT, LEFT
...
Deswegen:
10 - an Befehlsdekodierer: func feld
Das geht so:
100 000 - add - dieser ist redudant - 00 beudetet immer add, zwischen (1) und (2) 10 nutze func feld, hier noch mal add
100 010 - sub
100 100 - and
100 101 - or
101 010 - slt
100 000 - 4 0
100 010 - 4 2
100 100 - 4 4
100 101 - 4 5
101 011 - 5 2
Das kann man sich nicht merken. Also wer linux kann, kann sich rechte merken
rwx
111 - rwx
110 - rw
101 - rx
100 - r
011 - wx
010 - w
001 - x
000 - nichts
da kann man sich 4 0, 4 2... noch merken
vom Funktionskekodier an ALU
001 add
110 sub
000 and
001 or
111 slt
das ist vom Funktionsdekodier an ALU
Das andere func Feld im Befehl
und 2 Bit Befehlsdekodierer Funktionsdekodier
und 5 Bit Opcode