Sie befinden sich hier: Termine » Prüfungsfragen und Altklausuren » Hauptstudiumsprüfungen » Lehrstuhl 3 » CPU Entwurf mit VHDL   (Übersicht)

CPU Entwurf mit VHDL

Prüfer: Marc Reichenbach
Beisitzer: Konrad Häublein

Vorbereitung/Allgemeines

Zur Vorbereitung bin ich die Folien mehrmals durchgegangen. Die Vorlesung beinhaltet gegen Ende ein kleines Projekt, welches ich mit meinem Partner vor der Prüfung bearbeitet hatte, was beim VHDL-Wiederholen durchaus hilfreich war. Ansonsten habe ich mir die CPU aus der Übung nochmal angesehen. Für die eigentliche Prüfung sind auch die Tafelskizzen und Ausführungen Marcs während der Vorlesung sehr wichtig, dementsprechend habe ich meine Mitschriften nochmals durchgearbeitet.

Prüfung mit Papier und Stift. Ich musste sowohl etwas VHDL schreiben als auch RTL-Schematik und eine minimale CPU skizzieren. Die Fragen wurden nur vom Prüfer gestellt. Marc schaut die ganze Zeit leicht kritisch, auch wenn man das Richtige sagt, davon darf man sich nicht verunsichern lassen. Die Atmosphäre war angenehm.

Prüfungsablauf

Die Prüfung war ungefähr 50/50 zwischen VHDL und CPU-Design aufgegliedert, allerdings hat Marc bei VHDL leicht überzogen. Generell war die Prüfung sehr ähnlich zum anderen Prüfungsbericht von diesem Semester.

VHDL

Allgemein

F: Was ist VHDL?

  • Spezifikations- und Modellierungssprache mit synthesefähigen Anteilen

F: Synthesefähige Anteile. Wie beschreibe ich das?

  • Struktur-, Datenfluss-, Prozessbeschreibung

F: Wie ist eine normale VHDL-Datei aufgebaut?

  • Bibliotheken
  • Entity-Beschreibung („Schnittstelle“)
  • Architektur („funktionales Verhalten“)
  • Konfiguration („Auswahl einer bestimmten Architektur“)

F: Bibliotheken. Was nutzt man denn da wichtiges, und braucht man eigentlich immer?

  • IEEE-standard lib (genauer Name war nicht gefragt). Standardtypen, bspw. std_logic, std_logic_vector.
  • Auf Nachfrage: 9-wertige Logik, warum will man das…

F: Bitte einen Zähler in VHDL schreiben.

	signal count : std_logic_vector(...); -- je nach breite
 
	process(clk, reset)
	begin
		if reset = '1' then -- asynchrones Reset
			count <= "00...";
		elsif clk'event and clk = '1' then -- wir wollen einen getakteten Speicher
			count <= count + 1;
		end if;
	end process;

F: Bitte die RTL dazu aufmalen.

    --------------------------------|
    |                               |
    |  |-----|        |----------|  |
    |--|     |        |          |  |
       |  +  |--------| Register |--|
  '1'--|     |        |          |
       |-----|   |---->          |
                 |    |          |
                 |    |----------|
                 |         |
                clk      reset

F: Wie schnell kann der Counter jetzt takten?

  • Abhängig von der Geschwindigkeit des Addierers
  • → kritischer Pfad: Wo geht er durch, wovon ist er abhängig (breite des Addierers, kurz Carry-Ripple vs Carry-Lookahead erklärt)

FPGA

F: Wie kommt VHDL auf das FPGA

  • Synthese („VHDL → RTL“)
  • Implementierung (besonders der Unterschied zwischen Mapping und Place & Root wurde gefordert)
    • Translation (Linker für Netzlisten, dazu Übergang von Unisim → Simprim, also Simulationskomponenten → Highlevel FPGA-Beschreibung)
    • Mapping (Welche Elemente für die jeweiligen Komponenten, z.B. ein AND → LUTs)
    • Place & Root (Welche LUT des FPGAs und wie zu verbinden)

Funktionale Simulation

F: Warum will man simulieren?

  • In Hardware schwer reinzusehen, Schwingungen, semistabile Signale…
  • Buskonflikte, etc.
  • Hardware bauen ist teuer/zu teuer und langwierig für „mal schnell Testen“

F: Wie funktioniert das?

  • Kompilierung
  • Elaboration
  • Initialisierung
  • Ereignisgesteuerte Simulation (Warum macht man das? → Diskretisierung)
    • Ereignislisten an Signalen mit Timestamps für die Ereignisse/Transaktionen
    • Deltazyklen zur Lösung paralleler Zuweisungen, da CPUs sequentiell → „logische Uhr“

CPU

F: Jetzt haben wir ja so einen Counter. Wofür ist der gut einsetzbar?

  • Program Counter

Single Cycle CPU

F: Elemente einfacher CPU? ( + hinmalen und grob „verdrahten“)

  • Program Counter
  • Instruction Memory
  • Register File
  • ALU
  • Data Memory
  • + Decoder, Additionswerke für PC und Branches, …
  • siehe Folien ;)

F: Auch ohne RegFile möglich?

  • Ja, man könnte auch SRAM/BRAM verwenden
  • Memory only
  • Stack- oder Akkumulatorbasierte Architektur

F: Jeweils Datenpfade für folgende Anweisungen erklären:

add $1, $2, $3     # Allgemein
sw  $5, 16($4)     # Registerwert an ALU vorbeizuschleifen
add $4, $1, $2, $3 # Add mit drei Registern

F: Ist Instruktion drei möglich?

  • Erwartete Antwort: Nein, weil es bei unserer Übungs-CPU nicht geht
  • Auck ok war: Ja, aber:
    • Regfile mit drei Readeingängen, ALU mit drei Eingängen oder
    • Mikroprogrammierung
    • Assembler-Makro, welches zu zwei adds und einem Temporärregister (reserviert dafür) „übersetzt“

Pipelining

Aus Zeitgründen wurde der allgemeine Teil übersprungen (Stufen einzeichnen, o.Ä.).

F: Wir wollen die ALU pipelinen. Was muss man beachten

  • Je nach Mächtigkeit der ALU
  • Adder, Mult, Cordic lassen sich super Pipelinen
  • Aber: Barrel-Shifter lässt sich zwar Pipelinen aber Forwarding nicht sinnvoll möglich weil sich in jedem Schritt alle Bits ändern können (Auf Nachfrage musste ich einen Barrelshifter hinmalen)

F: Wo kann in unserer CPU ein Strukturhazard auftreten?

  • Optional wenn Instruction Memory und Data Memory identisch
  • Lösung: Stalls oder auf Ebene weiter darunter (z.B. Caches) verschieben

F: Bitte die Lösung mit der Ebene Aufzeichnen

  • I$, D$, Arbiter, L2-$, RAM

F: Wie würde man denn so einen Arbiter bauen

  • Viele Möglichkeiten: Simpel: Statemachine und D$ vor I$ bedienen
  • Statemachine hinmalen
                            /------------\
         |----------------->|    idle    |<-------------------------------------|
         |                  \------------/                                      |
         |                       /  \                                           |
         |                      /    \                                          |
         |    i$req && !d$req  /      \ d$req                                   |
         |                    v        v                                        |
         |           /---------\      /---------\                               |
         |           | i$fetch |      | d$fetch |                               |
         |           \---------/      \---------/                               |
         |               ...              ...      <- Get the data from memory  |
         |           /---------\      /---------\                               |
         |           |  i$fin  |      |  d$fin  |                               |
         |           \---------/      \---------/                               |
         |                |                |                                    |
         |----------------|                |------------------------------------|
    
  • Geht das minimaler? Ja, d$fetch und Idle zusammenfassen. Aber dann unnützer Verkehr auf dem Speicherbus → Bspw. bei Multicore idiotisch.