# MU1-Rechner
## Was kann er mehr:
- Indirekte Adressierung
- Schleifen
- Unterprogramme (Strukturen)
- Optimieren der Datenzugriffe (schneller)

## ALU
### Verbesserungen
- Funktionen der ALU
  - **A+B** ist der Ausgang des Addierers
  - **A-B** wird gebildet als **A+nichtB+1**
  - **B** wird implementiert, indem A fest auf 0 gesetzt wird
  - **A+1** wird implementiert, indem Eingang B fest auf 0 und Carry-Eingang auf 1 gesetzt wird

![image_54.png](image_54.png)

### Grundfunktionen MU1-ALU
_Im Praktikum wird nur erwartet, dass Funktion bekannt ist, nicht bspw FA, FIA, etc._
- FA: Funktion (0, A) (also eig. F0A)
- FB: Funktion (0, B)
- FIA: Funktion (Inverter, A)
- FIB: Funktion (Inverter, B)
- FC: Funktion (F1, Carry-Flag)
- F1: Funktion (0/1)
- FS: Funktionsergebnis Statusregister
- C: Funktionsergebnis C

![image_56.png](image_56.png)
![image_55.png](image_55.png)

## Der MU1-Datenpfad
- Das erweiterte Modell besitzt
  - Stackpointer SP
  - Register Din und Dout
- Laufzeiten sind kürzer pro Takt
  - Takt kann erhöht werden
- Durch Din und Dout braucht es mehr Taktzyklen, diese sind aber schneller durchlaufen

![image_57.png](image_57.png)

## Der Reset
- Jeder Prozessor hat einen Reset-Eingang
  - ist negiert angelegt → 0 macht [reset](MU1Rechner.md#reset)
    - [Program Counter](MU0Rechner.md#steuerwerk) wird auf 0 gestellt, [Microprogram-Counter step](MU1Rechner.md#micro-program-counter-step) ebenfalls
    - ALU wird auf Funktion NULL gesetzt
- Beim Einschalten wird Reset-Signal verzögert gesetzt
  - Prozessor braucht Zeit um Startzustand herzustellen

## Micro-Program-Counter Step
- Step ist ein Speicher in der Steuereinheit (_Timing/Control Unit_)
- meiste Befehle benötigen mehrere Takte
  - Micro-Program-Counter Step gibt Steuerlogik Informationen
    - welche Aktionen sind auszuführen
    - Step = Eingangsinformation für jeden Schritt
- Steuerungstabelle weiß welcher step welcher Schritt ist

## Befehlsablauf MU1
![image_58.png](image_58.png)
- Step == Null
  - **Fetch** (lesen des Befehls in das Instruction Register)
- letzter Schritt: Step = Null
- Step wird meistens um 1 erhöht
  - falls nicht → Schleife

### Fetch-Zyklus
- findet in einem Takt statt
  - 1. Taktflanke
    - Program Counter wird auf Adressbus und auf ALU[A] geschaltet
    - An der ALU ist Befehl=A+1, S=0
  - 2. Taktflanke
    - Speicher liest nächste Instruktion und speichert in IR
    - PC wird über ALU um 1 erhöht

![image_59.png](image_59.png)
![image_80.png](image_80.png)

### Befehl LDA (Laden des AKK aus Speicher)
- Zwei Takte
- ![image_60.png](image_60.png)
- ![image_81.png](image_81.png)

### Zustandsbeschreibung des Ladebefehls
![image_61.png](image_61.png)
- Nach Fetch entscheidet Opcode im IR und Schrittnummer, welchen Zustand der Automat als nächstes annimmt
- Step ist PC im Microcode und beschreibt Abfolge der Befehle im Microcode
- Zu jedem Schritt gehört eindeutige Funktion
  - Lässt sich in Timing-Control-Logik umsetzen

## Adressierung
### Direkte Adressierung (STO/LDA)
![image_62.png](image_62.png)
- Befehl erhält direkt die Speicheradresse
  - Adresse kann zur Laufzeit nicht mehr verändert werden

### Indirekte Adressierung (STR/LDR)
![image_63.png](image_63.png)
- Adresse steht an Speicherstelle
  - effektive Adresse kann noch berechnet werden
    - Schleifen können programmiert werden

### Adressierungsarten
#### Unmittelbare Adressierung (_immediate_)
- Befehl erhält Konstante
  - bspw.: _ADD #1_

#### Direkte Adressierung (_direct, absolute_)
- Befehlt enthält Adresse im Speicher, an der sich Operand befindet
  - bspw.: _LDA S_ (_S gibt Adresse im Speicher an_)

#### Indirekte Adressierung (_indirect_)
- Befehl enthält Adresse, an der dich effektive Adresse mit Inhalt befindet
  - bspw.: _LDR S_ (_S gibt indirekte Adresse an_)


## Der Stack
- stellt dynamischen Zwischenspeicher dar
- Grundoperationen: [Push](MU1Rechner.md#stack-push), [Pop](MU1Rechner.md#stack-pop)
- Meiste Speicherlayouts (_Konventionen_) sehen vor:
  - wächst von oben nach unten
  - wächst von großen zu kleinen Adressen

### Stack - PUSH
![image_65.png](image_65.png)
- erniedrigt Stackpointer
- schiebt einen Wert in Speicherwort, auf das der Stackpointer zeigt

### Stack - POP
![image_66.png](image_66.png)
- liest ein Speicherwort von Adresse auf den der Stackpointer zeigt
- erhöht den Stackpointer

### Der Stack im Speicher
![image_64.png](image_64.png)
- Stackpointer wird auf Adresse am Ende des Speicherbereichs gesetzt
- Programme werden im unteren Speicherbereich platziert
  - Programm-Counter auf Adresse 0
- Programmbereich schließt sich nach oben an Datenbereich an
- Zwischen Daten und Stack findet man Heap

### Zugriffe auf den Speicher
![image_67.png](image_67.png)

## Unterprogramme
![image_68.png](image_68.png)
- wichtiges Strukturierungsmittel für Programmierung
- werden mit Sprungbefehl (_call, bl_) angesprungen
- Nach Verlassen des UP wird ursprüngliches Programm wieder fortgesetzt
  - Rücksprung erfolgt indem gespeicherte Adresse wieder in PC übertragen wird

### Unterprogramm Aufrufe
#### Call
![image_69.png](image_69.png)
- nächster nach der Rückkehr auszuführende Befehl wird auf den Stack gespeichert
  - Sprungadresse wird aus IR in PC geladen

#### Return
![image_70.png](image_70.png)
- Rücksprungadresse von Stack in PC geschrieben
  - fetch-Zyklus lädt neue Instruktion


## MU1-Befehlssatz
![image_71.png](image_71.png)

## Micro-Codes
**X = Y**
- Inhalt des Registers Y wird nach X verschoben

**X = [Y]**
- Inhalt von Adresse in Y wird nach X verschoben

**X = Y op Z**
- Inhalt von Y (A-Bus der ALU) wird mit Z (B-Bus der ALU) verrechnet und nach X transportiert

**[X] = Y**
- In Adresse in X wird Inhalt von Y geschrieben

**ACC = Din**
- ACC & Din sind Registernamen
  - Inhalt von Din wird nach ACC transportiert
- in Din muss oe gesetzt sein, in ACC muss ie gesetzt sein
- Transport über ALU
  - [ALU Funktion](MU1Rechner.md#grundfunktionen-mu1-alu) muss B sein
- Da Speicher nicht angesprochen wird (keine [ ])
  - [MEMeq=0](MU0Rechner.md#speicher-des-mu0) und [RnW beliebig (laut Rapp lieber 1)](MU0Rechner.md#speicher-des-mu0) 

**Din = [SP]**
- Inhalt von SP ist Adressinformation
  - Adressmultiplexer muss auf 0 stehen
- Da Speicher angesprochen wird
  - MEMrq = 1, RnW = 1
- Da ALU nicht benutzt wird
  - ALU-Funktion kann beliebig gesetzt werden

**PC = PC + 1**
- ALU-Funktion muss [A+1](MU1Rechner.md#grundfunktionen-mu1-alu) sein
- PC wird auf A-Bus gelegt
- in der zweiten Hälfte des Takts wird Ergebnis in PC geschrieben
- oe und ie von PC müssen 1 sein

**Din = [SP], SP = SP+1**
- Beide Operationen können in einem Takt durchgeführt werden
  - Adressierung in der ersten Takthälfte
  - Zurückschreiben in der zweiten Takthälfte

## Regeln für MU1
**[X] = Dout**
- wird in den Speicher geschrieben, muss rechte Seite [Dout](MU1Rechner.md#der-mu1-datenpfad) sein
- [MEMrq = 1, RnW = 0](MU0Rechner.md#speicher-des-mu0)
- zu schreibender Wert muss VORHER nach Dout gebracht werden

**X = [Y]**
- wird vom Speicher gelesen
  - linke Seite muss IR oder Din sein
- [MEMrq = 1, RnW = 1](MU0Rechner.md#speicher-des-mu0)

**keine Adresse**
- wird keine Adresse verwendet
  - [MEMrq = 0, RnW = 1](MU0Rechner.md#speicher-des-mu0)
- **Nur ein Register darf jeweils auf einen Bus schreiben (A- oder B-Bus), aber alle dürfen lesen**


## Die Addition ADD S
- IR wird zur Adressierung verwendet und der Wert nach Din gebracht
  - **Din = [IR]**
- Inhalt des AKK wird auf A-Bus gelegt, Inhalt von Din auf B-Bus
  - [ALU-Funktion](MU1Rechner.md#grundfunktionen-mu1-alu) ist **A+B, S:   ACC = ACC + DIN**

![image_72.png](image_72.png)

## Die Operation PUSH
**Akkumulator wird auf den Stack geschoben**
- Besteht aus 3 Schritten
  1. **SP = SP-1**
     - ![image_73.png](image_73.png)
  2. **Dout = ACC**
     - ![image_74.png](image_74.png)
  3. **[SP] = Dout**
    - ![image_75.png](image_75.png)
    - [Micro-Program-Counter Step](MU1Rechner.md#micro-program-counter-step) wird auf 0 gesetzt
      - Fetch-Zyklus schließt sich an

## MU1-Zustandsautomat für LDA, ADD, PUSH
![image_76.png](image_76.png)
- Nach dem Holen des Opcodes im Fetch-Zyklus
  - Zustand des OpCode wird angesprungen
- Step-Variable (PC im Micro-Code) wird in Schleife durchlaufen
  - endet bei 0 im Fetch-Zyklus


## Bedingte Sprünge
- Bedingter Sprung **JGE** (_Jump on greater or equal_) 
  - in Abhängigkeit des Negative-Flags im Statusregisters (~15 Bit des ACC, ACC >=0 oder ACC <0) wird ein unterschiedlicher Zustand angesprungen
    - ? N = 0 (ACC >= 0)
      - PC = IR
    - ? N = 1 (ACC < 0)
      - keine Operation wird ausgeführt (NOP)
- Bedingter Sprung **JNE** (_Jump on not equal)
  - strukturell gleich, Zusatzbedingung:
    - Accumulator = Null (Zero-Flag = 1)

### MU1-Steuerlogik für bedingte Sprünge
- Beide Befehle weisen 2 Zustände auf
  - unterscheiden sich durch Statusbits des Akkumulators
- Beide Zustände haben Schrittnummer 1 und Folgeschritt 0
- Funktion **NOP** (**N**o **Op**eration) ist gekennzeichnet
  - kein Registerinhalt wird verändert
    - Alle Register haben oe und ie auf 0
  - Speicher wird nicht angesprochen
    - MEMrq = 0
- ![image_77.png](image_77.png)

## Der Stop-Befehl
- hat als Folgezustand _stop_
- kein Fetch-Zyklus mehr
  - Zustandsmaschine wird in der Stellung angehalten
- ![image_78.png](image_78.png)

## Reset
- Zustandsmaschine geht in Zustand _reset_
  - PC = 0
  - Step = 0
- Beendigung des Reset-Signals mit dem fetch fortgefahren und Befehl von Adresse 0 wiederholt
- ![image_79.png](image_79.png)


## Zusammenfassung
- Funktionen ALU
- Neue Register Stackpointer, Din, Dout
- Micro-Programm-Counter Step
- Fetch-Zyklus
- Micro Programm + Micro Codes + Zustandsautomaten für LDA, ADD, Push, JGE, Stop, Reset
- Direkt und indirekte Adressierung
- Stack, Unterprogramme
- Beschreibung der Microcode-Funktion durch einfache Sprache
- Zentrales Register: ACC → Akkumulator-Architektur

## Probleme des MU1-Designs
- **Speichergröße**
  - begrenzt auf 4096 Worte (12Bit) bzw. 65k Worte (16Bit)
- **Anzahl Befehle**
  - Begrenzung auf 4 Bit breiten Opcode
- **Absolute Adressierung**
- **Adressberechnungen**
  - Müssen in einem Register zwischengespeichert werden
- **Nur ein Datenregister**
- **Berechnung Programmcounter**
  - Muss jedes Mal durch ALU erhöht werden → verlangsamt Prozessor

## [Weiterentwicklung MU2](MU2-3Rechner.md)