33

Tutorial zur Nutzung eines Mikroprozessor Cores am ... · Tutorial zur Nutzung eines Mikroprozessor Cores am Beispiel der MIPS Prozessorarchitektur Prof. Dr.-Ing. Michael Karagounis

Embed Size (px)

Citation preview

Tutorial zur Nutzung eines Mikroprozessor Cores am Beispiel

der MIPS Prozessorarchitektur

Prof. Dr.-Ing. Michael Karagounis

März 2019

Zusammenfassung

Ziel dieses Tutorials ist es den Aufbau, den Umgang und die Nutzungsmöglich-

keiten von Mikroprozessor Cores zu studieren. Durchgeführt wird das Tutorial

am Beispiel der MIPS32 microAptiv UP Prozessarchitektur unter Nutzung des

MIPSfpga Verilog Modells. Der Core wird unter Modelsim simuliert und auf dem

Artix Xilinx FPGA eines Nexys 4 Board von Digilent implementiert. Kurze C

Programme werden mit Codescape, welche eine gcc Cross-Compiler Toolchain

umfasst, programmiert und dann in die Simulation eingebunden. Programme

werden über das BusBlaster Hardwaremodule per JTAG Schnitsttelle in den

Programmspeicher des im FPGA implementierten Mikrocontrollers übertragen

und ausgeführt.

1

INHALTSVERZEICHNIS 2

Inhaltsverzeichnis

1 Projektstatus 3

2 Die MIPS Prozessorarchitektur 4

2.1 Core Blockdiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.2 Registersatz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.3 Befehlssatz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.3.1 Funktionale Gruppierung des Befehlssatzes . . . . . . . . . . . . . . . . . 62.3.1.1 Speichern und Laden von Daten aus dem Speicher . . . . . . . . 62.3.1.2 Arithmetisch-Logische Operationen . . . . . . . . . . . . . . . . 72.3.1.3 Programm�usskontrolle durch Programmsprünge . . . . . . . . . 8

2.3.2 Strukturelle Gruppierung des Befehlssatzes . . . . . . . . . . . . . . . . . 82.3.2.1 R-Typ Instruktionen . . . . . . . . . . . . . . . . . . . . . . . . . 92.3.2.2 I-Typ Instruktionen . . . . . . . . . . . . . . . . . . . . . . . . . 102.3.2.3 J-Typ Instruktionen . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.4 Pipeline Mikroarchitektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.5 Speicherorganisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152.6 AHB Lite Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172.7 Design Struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3 HDL Simulation 20

4 FPGA Implementation 24

5 Programmierung 28

5.1 Kompilier- und Assembliervorgang . . . . . . . . . . . . . . . . . . . . . . . . . . 305.2 Erstellung von Speicherinitialisierungsdateien . . . . . . . . . . . . . . . . . . . . 30

6 EJTAG Programm Upload & Debug 31

1 ÜBERBLICK 3

1 Überblick

Dieses Tutorial hat den praktischen Einstieg in Mikroprozessor Architekturen am Beispiel ei-nes MIPS Cores als Ziel und umfasst die Vorstellung des Befehlssatzes und dessen Abbildungin Hardware. Es werden die einzelnen Komponenten des Prozessorkerns und deren Funktionbeschrieben. Am Beispiel des MIPS32 microAptiv UP Cores kann die Umsetzung eines RISC(Reduced Instruction Set) Computers d.h. eines Prozessors mit geringer Anzahl von einfachenBefehlen, auf eine Pipelining Mikroachitektur mit hohem Befehlsdurchsatz studiert werden.

Mit Hilfe des frei verfügbaren MIPSfpga Verilog Modells werden auch Erfahrung im prakti-schen Umgang mit demMIPS Prozessorkern vermittelt. Der Prozessorkern wird in eine Testbenchintegriert und mit Modelsim simuliert. Mit Hilfe der Cross-Compiler Entwicklungswerkzeuge Co-descape werden unter Windows einfache C-Programme und Assemblerprogramme geschriebenund in die Simulation eingebunden. Darüber hinaus wird der Prozessorkern auf einem FPGAimplementiert und einfache Programme ausgeführt. Die Programmierung wird sowohl durchDe�nition von Default-Speicherinhalten während der Synthese als auch durch Nutzung einerspeziellen JTAG Debug- und Programmierschnittstelle in den auf dem FPGA implementiertenMikrocontroller übertragen.

Das Tutorial ist wie folgt aufgebaut. In Kapitel 2 erfolgt eine Darstellung des MIPS Befehls-satzes und der Mikroarchitektur. In Kapitel 3 wird die Vorgehensweise bei der Simulation desMIPS Mikrocontrollers erläutert. Im Kapitel 4 werden die Schritte für die Implementierung desModells auf dem Artix Xilinx FPGA eines Nexys 4 Board von Digilent erklärt. Die Erstellungvon lau�ähigen Programmen und der Programm-Upload über die EJTAG Schnittstelle wird inKapitel 5 bzw. 6 beschrieben.

Mittelfristig soll das Tutorial um eine Beschreibung für die Ausführung eines LINUX Be-triebssystems auf dem im FPGA implementierten Mikrocontroller erweitert werden. Darüberhinaus sind weitere Inhalte für ein vertieftes Verständnis der Funktionsweise des Mikrocontrollerssinnvoll. Von Interesse sind dabei einerseits weitere Kenntnisse über Funktionsdetails der ver-schiedenen Betriebsmodi, der Speicherverwaltungsmechanismen, des Power-Managements unddes MicroMips Befehlssatzes. Andererseits kann durch eine Analyse des HDL Codes erkanntwerden, wie die in der Dokumentation beschriebene Funktion des Mikrocontrollers im HDL Co-de abgebildet wird. Hierfür wäre die Erarbeitung eines Überblicks zur hierarchischen Strukturder einzelnen HDL Module, Ihrer Funktion und Ihrem Zusammenspiel hilfreich wenn auch sehrzeitaufwendig.

Die Inhalte dieses Tutorials basieren zu groÿen Teilen auf den englischsprachigen MIPSfpgaTutorials und dem Buch Harris, Digital Design and Computer Architecture, Morgan Kaufmann,2012

2 DIE MIPS PROZESSORARCHITEKTUR 4

2 Die MIPS Prozessorarchitektur

In diesem Kapitel wird der Befehlssatz, der Registersatz und die Mikroarchitektur des MIPSMikroprozessors vorgestellt. Darüber hinaus werden alle Komponenten des MIPS Modells undderen Funktion beschrieben.

2.1 Core Blockdiagramm

Der untersuchte Mikrocontroller Core hat eine MIPS32 microAptiv UP Architektur und wirdim Rahmen des MIPSfpga Programmes Universitäten und Forschungseinrichtungen zugänglichgemacht. Ein Blockdiagramm, welches die Hauptkomponenten des Cores visualisiert, ist in Ab-bildung 1 dargestellt.

COP2

Interface

UDI

Interface

Interrupt

InterfaceMDU

Power

Management

Execution

Unit

System

Coprocessor

Instruction Decoder

GPR

D-Cache

ControllerD-Cache

Memory

Management

Unit

I-Cache

ControllerI-Cache

D-SRAM

Interface

I-SRAM

Interface

Bus

Interface

Unit

Debug and

Profiler

JTAG

Interface

D-SRAM

Interface

AHB-Lite

Interface

I-SRAM

Interface

Abbildung 1: Blockdiagramm des MIPS32 mircoactive UP Cores

Der Prozessorkern hat eine 32 Bit Architektur und besitzt eine 5 stu�ge Befehls-Pipeline zurOptimierung des Befehlsdurchsatzes. In der Abbildung sind die zentralen Elemente des Prozes-sorkerns rot hinterlegt. Der Instruction-Decoder erhält den aktuellen Befehl aus dem Instruction-Cache, der einen schnellen Zwischenspeicher mit geringen Zugri�slatenzzeiten darstellt und teiltnach der Befehlsdekodierung der Execution Unit die auszuführende Operation mit. Die ExecutionUnit schlieÿt unter Anderem eine arithmetisch logische Einheit (ALU) mit Hilfe derer arithme-tische und bitweise logische Operationen ausgeführt werden können. Des Weiteren besitzt sieeine Adresseinheit mit der die Adressen von im Speicher abgelegten Daten und die nächste Be-fehlsadresse ermittelt werden kann. Die Execution Unit verfügt auch Logik zur Erkennung vonSprung und Trap Bedingungen und zur Vervollständigung und Ausrichtung von Daten und Be-fehlsparametern, die mit einer Bitbreite kleiner als 32 Bit geladen und gespeichert werden sollen.Im Block GP be�ndet sich der Registersatz der Architektur in dem Parameter und Resultatevon Befehlen abgelegt werden können. Daten können aus dem Datenspeicher in den Registersatzund vom Registersatz in den Datenspeicher abgelegt werden.

2 DIE MIPS PROZESSORARCHITEKTUR 5

Um die Latenzzeiten der Speicherzugri�e zu reduzieren, steht auch für den Datenspeicher eineCache zur Verfügung. Sowohl für den Daten- als auch den Programm-Cache regelt ein Controllerdie Bevorratung mit oft genutzten Daten und die Synchronisierung mit dem Hauptspeicher. DieMIPS Architektur ermöglicht den Anschluss komplett unabhängiger Bausteine für den Daten-und den Programmspeicher über zwei getrennte Busse D-SRAM bzw I-SRAM, was im Prinzipdem Ansatz einer Harvard Architektur entspricht. Zusätzlich ist es möglich über einen AHB-Lite Bus einen gemeinsamen Hauptspeicher an den Core anzuschlieÿen, der dann von der BusInterface Unit verwaltet und angesprochen wird, was dem Ansatz einer von-Neumann Architekturentspricht. Im Rahmen dieses Projektes wird der Controller mit einem einzelnen gemeinsamenHauptspeicher über den AHB-Lite Bus angeschlossen. Die Memory Management Unit übersetztvirtuelle Adressen in physikalische Adressen und nimmt die Anfragen für die Schreib-Lesezugri�eder Cache Controller auf den Hauptspeicher entgegen und übergibt sie priorisiert an den BusInterface Unit Baustein.

In der MIPS Architektur sind optional bis zu vier Coprozessoren CP0-CP3 vorgesehen, vondenen CP0 zwingend vorhanden sein muss. Durch den Coprozessor CP0 wird der Betriebsmodusdes Hauptprozessors (User, Kernel, Debug) und die Arbeitsweise des virtuellen Speichers (FixedMapping Translation oder Translation Lookaside Bu�er) bestimmt. Der Coprozessor CP0 über-nimmt auch wichtige Systemaufgaben wie die Kon�guration und die Handhabung von Interruptsund Exceptions, die Einstellung des Timers, die Ermittlung von Performance Kennwerten unddie Steuerung von Debugging Vorgängen. CP1 entspricht der Coprozessoreinheit zur Berechnungvon Flieÿkommazahlen FPU während CP2 und CP3 bei Bedarf anwendungsspezi�sch entworfenwerden können. Im Rahmen dieses Projektes wird nur der System Coprozessor C0 verwendet.

Das Interrupt Interface ermöglicht die Einkopplung externer Interrupts, welche von periphä-ren Komponenten wie Kommunikationsprotokolleinheiten oder I/O Geräten generiert werden.Im Rahmen des Projektes werden externe Interruptquellen jedoch nicht genutzt. Die Multiple/-Divide Unit (MDU) kann die Resultate mehrerer Multiplikationen bzw. Divisionen akkumulierenund damit DSP Algorithmen mit hoher Geschwindigkeit ausführen. Über das User De�ned In-terace (UDI) ist es möglich anwendungsspezi�sche Instruktionen zu implementieren und auf denRegistersatz des Cores genau so wie bei regulären Befehlen zuzugreifen. Dieses Feature wirdjedoch im Rahmen des Projektes nicht genutzt. Über das JTAG Interface ist es möglich De-bugging Vorgänge durchzuführen, Leistungpro�le aufzunehmen und Softwareprogramme in denProgrammspeicher zu laden.

2.2 Registersatz

Die MIPS Architektur umfasst einen Satz von 32 Mehrzweckregistern ($0,$1,...,$31), den Pro-grammzähler (pc) und zwei Spezialregister (hi,lo), welche nur bei Multiplikationen und Divisionenverwendet werden. Alle Register besitzen eine Breite von 32 Bit. Der Programmzähler trägt dieSpeicheradresse des nächsten Befehls, der ausgeführt werden soll. Bei Integer Multiplikationenwird das Ergebnis mit 64 Bit Breite abgespeichert. Das höherwertige Datenwort des Produkteswird in das hi und das niederwertige Datenwort in das lo Register abgelegt. Bei Integer Divisio-nen wird der Quotient als 32 Bit Wort im lo Register gespeichert, während der Divisionsrest inshi Register geschrieben wird.

Das erste und das letzte Mehrzweckregister ist für spezielle Funktionen reserviert. Register $0ist fest mit dem Wert Null verdrahtet d.h. alle Bits des Registers tragen den logischen Wert '0'.Dieses Register wird immer dann als Datenquelle verwendet, wenn der Wert Null als Parametereines Befehls benötigt wird. Wird $0 als Zielregister einer Instruktion angegeben, so wird dasErgebnis der Operation verworfen. Das letzte Register $31 wird zur automatischen Sicherung

2 DIE MIPS PROZESSORARCHITEKTUR 6

der Rücksprungadresse beim Aufruf einer Funktion genutzt. Hierfür existieren spezielle Sprung-befehle, die vor Ausführung des Sprunges den aktuellen Programmzählerstand in Register $31ablegen. Aus Hardware Sicht besteht keine Einschränkung bei der Nutzung der restlichen 30 Re-gistern. Nichtsdestotrotz hat sich eine Konvention bezüglich der Registerverwendung etabliert,welche in Tabelle 1 aufgelistet ist. Programme, welche die Registerkonvention nicht einhalten,sind zwar lau�ähig, können jedoch beim Zusammenspiel mit bereits existierender Software Kom-patibilitätsprobleme erzeugen.

Name Nummer Verwendungzsweck

$0 0 Konstanter Wert Null$at 1 Temporäre Variablen des Assemblers$v0-v1 2-3 Funktionsrückgabewerte$a0-a3 4-7 Funktionsargumente$t0-t7 8-15 Temporäre Variablen$s0-s7 16-23 Gesicherte Variablen$t8-$t9 24-25 Temporäre Variablen$k0-$k1 26-27 Temporäre Variablen des Betriebssystems (Interrupts/Traps etc.)$gp 28 Globaler Zeiger in die Mitte des aktuellen 64 Bit Speichersegments$sp 29 Stack Zeiger auf den nächsten freien Speicherplatz$fp 30 Frame Zeiger beinhaltet Basisadresse des Stacks$ra 31 Rücksprungadresse nach Ausführung eines Unterprogramms

Tabelle 1: Konvention über die Nutzung des MIPS Registersatzes

2.3 Befehlssatz

Der Befehlssatz der MIPS Architektur wurde nach dem RISC (Reduced Instruction Set Compu-ter) Ansatz konzipiert. RISC Befehlssätze zeichnen sich durch eine geringe Anzahl von Befehlenmit einfacher Funktion aus. Bedingt durch die durchgehend niedrige Komplexität der Befehle, istauch die Variation der Ausführungszeiten minimal, was Vorteile bei der Parallelisierung und Se-quentialisierung der Befehlsverarbeitung hat und zu höheren Durchsatzraten führt. Im folgendenwerden die Befehle nach Ihrer Funktion und nach der Format Ihres Befehls-Codes kategorisiertund beispielhaft einige wichtige exemplarisch Befehle erläutert. Ein vollständige Au�istung allerBefehle �ndet sich im Anhang.

2.3.1 Funktionale Gruppierung des Befehlssatzes

Die Befehle lassen sich grob in die folgenden Funktionsgruppen zusammenfassen:

� Datentransfer (Speichern, Laden...)

� Arithmetisch-Logische Operationen (Addieren, Subtrahieren, UND, ODER,...)

� Programm�usskontrolle (bedingte und unbedingte Sprünge)

� Flieÿkommazahlen

2.3.1.1 Speichern und Laden von Daten aus dem Speicher

Der Speicher des MIPS32 ist mit einer Wortbreite von 32 Bit organisiert. Die Adressierung erfolgtjedoch byte-weise, sodass sowohl ganze Wörter (32 Bit), Halbwörter (16 Bit) als auch einzelne

2 DIE MIPS PROZESSORARCHITEKTUR 7

Menmonik Beschreibung Funktion

lb rd, of(rs) Vorzeichengerechtes Laden eines Bytes rd = mem[rs + of]lbu rd, of(rs) Vorzeichenloses Laden eines Bytes rd = mem[rs + of]lh rd, of(rs) Vorzeichengerechtes Laden eines Halbwortes rd = mem[rs + of]lhu rd, of(rs) Vorzeichenloses Laden eines Halbwortes rd = mem[rs + of]lw rd, of(rs) Laden eines Wortes rd = mem[rs + of]sb rs, of(rt) Speichern des niederwertigsten Registerbytes mem[rt + of] = rs[7:0]sh rs, of(rt) Speichern des niederwertigen Registerhalbwortes mem[rt + of] = rs[15:0]sw rs, of(rt) Speichern eines Wortes mem[rt + of] = rs

Tabelle 2: Auswahl arithmetischer Operationen

Bytes (8 Bit) vom Speicher gelesen bzw. in den Speicher geschrieben werden können. Da Wörteraus 4 Bytes zusammengesetzt sind, entsprechen Wortadressen immer einem Vielfachen von 4. Diezuverwendende Adresse wird aus zwei Komponenten zusammengesetzt. Ein Adressbestandteilist in einem Register rs abgelegt. Zu diesem Wert wird noch eine 16 Bit breite Konstante of

addiert, die während der Programmierung festgelegt wird und in den Befehlscode ein�ieÿt. BeiBytes welche unter Berücksichtigung des Vorzeichens in das Zielregister geladen werden sollen,werden die höherwertigen Bits des Registers mit dem Vorzeichenbit gefüllt. Bei Befehlen, welchedie Erweiterung �u� in der Befehlsbezeichnung tragen, werden die höherwertigen Bits auf Nullgesetzt.

2.3.1.2 Arithmetisch-Logische Operationen

Mathematische Operationen können unter Berücksichtigung des Vorzeichens nach der Logik derZweierkomplementdarstellung und mit Überlauferkennung erfolgen. Befehle welche die Operan-den ohne Vorzeichen und Überlauferkennung verarbeiten, tragen ein �u� in der mnemonischenBefehlsbezeichnung. Befehle mit einem �i� in der Namensbezeichnungen verwenden für die Ope-ration ein Literal im (Immediate) d.h. einen konstanten Operanden mit 16 Bit Wortbreite, derzum Zeitpunkt der Programmierung bereits feststeht und einen Operanden aus dem Register-satz rs (Register Source). Alle übrigen Befehle entnehmen beide Operanden rt (Register Target)und rs dem Registersatz, welche sich somit dynamisch während der Programmlaufzeit verändernkönnen. In allen Fällen wird das Ergebnis der Operation in ein Register rd (Register Destinati-on) abgelegt. Die verwendeten Register rs, rt, und rd können frei aus dem Registersatz gewähltwerden. Einzige Ausnahme sind die Ergebnisse der Division und Multiplikation, die in spezielleRegister lo und hi abgelegt werden.

Menmonik Beschreibung Funktion

add rd, rs, rt Addition zweier Registerwerte rd = rs + rtaddi rd, rs, im Addition einer Konstante mit einem Registerwert rd = rs + imaddu rd, rs, rt Vorzeichenlose Addition zweier Registerwerte rd = rs + rtdiv rs, rt Division zweier Registerwerte lo = rs / rt

Ermittlung des ganzzahligen Ergebnisses und Rest hi = rs % rtsub rd, rs, rt Subtraktion zweier Registerwerte rd = rs � rtsubu rd, rs, rt Vorzeichenlose Subtraktion zweier Registerwerte rd = rs � rtmult rs, rt Multiplikation zweier Registerwerte HI = (rs * rt)[63:32]

Das Produkt hat eine 64 Bit Wortlänge LO = (rs * rt)[31: 0]

Tabelle 3: Auswahl arithmetischer Operationen

2 DIE MIPS PROZESSORARCHITEKTUR 8

Menmonik Beschreibung Funktion

and rd, rs, rt Bitweise UND Operation zweier Registerwerte rd = rs & rtandi rd, rs, im Bitweise UND Operation zwischen einer Konstante rd = rs & im

und einem Registerwertor rd, rs, rt Bitweise ODER Operation zweier Registerwerte rd = rs | rtori rd, rs, im Bitweise ODER Operation zwischen einer Konstante rd = rs | im

und einem Registerwertxor rd, rs, rt Bitweise NOR Operation zweier Registerwerte rd = rs ⊗ rtxori rd, rs, im Bitweise NOR Operation zwischen einer Konstante rd = rs ⊗ im

und einem Registerwert

Tabelle 4: Auswahl logischer Operationen

Einige Schiebeoperationen verwenden eine Konstante �a� mit 5 Bit Breite, um die Schie-beweite festzulegen. Schiebeoperationen mit dem Namenszusatz �v� nutzen ein Register für dievariable Festlegung der Schiebeweite während der Laufzeit. Es wird zwischen arithmetischen undlogischen Rechtsschiebeoperationen unterschieden. Bei logischen Schiebeoperationen werden freiwerdende Bits mit Nullen aufgefüllt bei arithmetischen Schiebeoperationen werden die Bits unterBerücksichtigung des Vorzeichenbits aufgefüllt. Dementsprechend werden Null aufgeüllt, wenndie Zahl positiv ist, während bei negativen Zahlen Einsen nachgeschoben werden.

Menmonik Beschreibung Funktion

rotr rd, rs, a Konstante logische Rotation nach Rechts rd = {rs[a-1:0],rs[31:a]}rottv rd, rs, rt Variable logische Rotation nach Rechts rd = {rs[rt-1:0],rs[31:rt]}sll rd, rs, a Konstante logische Linksschiebeoperation rd = rs � asllv rd, rs, rt Variable logische Linksschiebeoperation rd = rs � rtsra rd, rs, a Konstante arithmetische Rechtsschiebeoperation rd = rs � asrav rd, rs, rt Variable arithmetische Rechtsschiebeoperation rd = rs � rtsrl rd, rs, a Konstante logische Rechtsschiebeoperation rd = rs � asrlv rd, rs, rt Variable logische Rechtsschiebeoperation rd = rs � rt

Tabelle 5: Auswahl Schiebeoperationen

2.3.1.3 Programm�usskontrolle durch Programmsprünge

Je nach Befehl werden Sprünge absolut (Jump) oder relativ zur Adresse des Programmzählers(Branch) durchgeführt. Die absolute Sprungadresse wird optional durch eine Konstante ad mit26 Bit Breite angegeben. Diese Konstante wird um zwei Bits nach links geschoben und umdie 4 hochwertigsten Bits des aktuellen Wert des Programmzähler ergänzt. Alternativ kann dieabsolute Adresse aus einem rs Register entnommen, die sich dynamisch während der Laufzeit desProgrammes ergeben kann. Bei relativen Sprüngen wird die Sprungweite durch eine konstantenO�set of mit 16 Bits Breite angegeben. Der O�set wird arithmetisch um zwei Bits nach linksgeschoben und auf pc+4 aufsummiert wird. Für Funktionsaufrufe existieren Befehle mit demNamenszusatz l, die zusätzlich vor dem Sprung die aktuelle Adresse des Programmzählers pc+8im Return-Register $ra sichert.

2.3.2 Strukturelle Gruppierung des Befehlssatzes

Die mnemonischen Befehlsbezeichnungen sollen die Lesbarkeit des Assembler-Codes verbessernund stellen im Prinzip nur eine Gedächtnisstütze für den Programmierer dar. Aus Hardwaresicht

2 DIE MIPS PROZESSORARCHITEKTUR 9

Menmonik Beschreibung Funktion

bal of Unbedingter Sprung und Sicherung der Rücksprung- pc = pc + (of �2)adresse $ra =pc + 8

beq rs, rt, of Sprung bei Gleichheit zweier Registerwerte pc = pc + (of�2)bgez rs, of Sprung wenn Registerwert gröÿer oder gleich Null pc = pc + (of�2)bgezal rs, of Sprung wenn Registerwert gröÿer oder gleich Null pc = pc + (of�2)

Sicherung der Rücksprungadresse $ra =pc + 8bgtz rs, of Sprung wenn Registerwert gröÿer Null pc = pc + (of�2)blez rs, of Sprung wenn Registerwert kleiner oder gleich Null pc = pc + (of�2)bltz rs, of Sprung wenn Registerwert kleiner Null pc = pc + (of�2)bltzal rs, of Sprung wenn Registerwert kleiner Null und pc = pc + (of�2)

Sicherung der Rücksprungadresse $ra =pc + 8bne rs, rt, of Sprung bei Ungleichheit zweier Registerwerte pc = pc + (of�2)j ad Unbedingter absoluter Sprung pc= pc[31:30] & (ad � 2)jal ad Unbedingter absoluter Sprung und Sicherung der pc= pc[31:30] & (ad � 2)

Rücksprungadresse $ra = pc + 8jalr rd, rs Unbedingter absoluter Sprung an dynamische pc = rs

Adresse und Sicherung der Rücksprungadresse $ra = pc +8

Tabelle 6: Auswahl von Sprungbefehlen

besitzen alle Befehle ein Bitmuster mit einer Breite von 32 Bit, welche den Befehl und dieverwendeten Parameter codieren. Die MIPS Architektur besitzt drei Instruktionsformate, diesich in der Bedeutung bzw. Funktion einzelner Bitgruppen unterscheiden.

� R-Typ (Nutzung von drei Registern)

� I-Typ (Nutzung von zwei Registern und einer 16-Bit Konstante)

� J-Typ (Nutzung einer einzigen 26-Bit Konstante)

2.3.2.1 R-Typ Instruktionen

Die Bezeichnung R-Typ steht für die Abkürzung Register-Typ. R-Typ Anweisungen nutzendrei Register während der Ausführungen, wobei die zwei Register rs und rt als Operanden d.h.Datenquellen dienen und das dritte Register rs, das Ergebnis der Operation speichert. Wie inAbbildung 2 dargestellt, besitzt der Maschinen-Code eines R-Typ Befehls die Felder: op, rs, rt, rd,shamt und funct mit jeweils 5 bzw 6 Bit Breite. Die auszuführende Operation ist in den Feldernop (Operation Code) und funct (Function Code) abgelegt. Alle R-Typ Befehle besitzen einen op

Code von 0 und die eigentliche Instruktion wird im funct Feld festgelegt. Die Operanden desBefehls werden in den drei Feldern textitrs, rt, rd kodiert und entsprechen den Registernummernaus Tabelle 1. Das shamt Feld wird nur bei Schiebeoperationen ausgewertet und beinhaltet dieAnzahl der Bits um die geschoben werden soll.

6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit

op rs rt rd shamt funct

Abbildung 2: Instruktionsformat eines R-Typ Befehls

2 DIE MIPS PROZESSORARCHITEKTUR 10

In Abbildung 3 ist der Maschinen-Code der R-Typ Befehle add und sub dargestellt. Währenddas Zielregister im Assembler Code an erster Postion steht, erscheint die Bitkombination, die dasZielregister de�niert, im Maschinen Code erst an der dritten Stelle.

0 17 18 16 0 32add $s0, $s1, $s2 00000 10001 10010 10000 00000 100000 0x02328020

Assember Dezimale Feldwerte Binär Code Hex Code

6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit

0 11 13 8 0 34sub $t0, $t3, $t5

6 Bit 5 Bit 5 Bit 5 Bit 5 Bit 6 Bit

00000 01011 01101 01000 00000 100010 0x016D4022

op rs rt rd shamt funct op rs rt rd shamt funct

Abbildung 3: Instruktions-Code eines add und eines sub Befehls

2.3.2.2 I-Typ Instruktionen

Die Bezeichnung I-Typ steht für die Abkürzung Immediate-Typ, was die Tatsache umschreibt,dass ein Operand unmittelbar im Befehlscode codiert ist und nicht einem Register entnommenwird. Wie in Abbildung 4 dargestellt, besitzen I-Typ Befehle die vier Felder op, rs, rt und imm.Die ersten drei Felder sind mit denen des R-Typs identisch, während das imm Feld der Konstantemit 16 Bit Breite entspricht, welche im Zweierkomplement angegeben wird. Das Register rs unddie Konstante imm werden dabei immer als Datenquelle verwendet. Das Register rt wiederumwird für manche Befehle wie z.B. addi und lw als Zielregister und für andere wie z.B. sw alsQuellregister verwendet.

6 Bit 5 Bit 5 Bit 16 Bit

op rs rt imm

Abbildung 4: Instruktionsformat eines I-Typ Befehls

In Abbildung 5 ist der Maschinen-Code einiger I-Typ Befehle dargestellt. Wenn rt als Zielre-gister verwendet wird, steht es im Assembler Code an erster Stelle, während die Bitkombination,die das Zielregister de�niert, im Maschinen-Code erst im zweiten Registerfeld aufgeführt wird.Zu berücksichtigen ist auch, dass die Konstante -12 im Zweierkomplement im Befehl angegebenwird.

8 17 18 5addi $0, $1, 5 001000 10001 10000 0000 0000 0000 0101 0x22300005

Assember Dezimale Feldwerte Binär Code Hex Code

6 Bit 5 Bit 5 Bit

8 19 8 -12addi $t0, $s3, -12

6 Bit 5 Bit 5 Bit 16 Bit

001000 01011 01000 0x2268FF4

op rs rt imm op rs rt imm

35 0 10 32 100011 00000 01010

43 9 17 4 101011 01001 10001

lw $t2, $s3, 32($0)

lw $t0, 4($t1)

1111 1111 1111 0100

0000 0000 0010 0000

0000 0000 0000 0100

16 Bit

0x8C0A0020

0xAD31004

Abbildung 5: Instruktions-Code verschiedener I-Typ Anweisungen

Bei den meisten I-Typ Befehlen wird die 16 Bit-Konstante unter Berücksichtigung des Vorzei-chens auf 32 Bit erweitert, bevor die eigentliche Operation durchgeführt wird. Bei einer positiven

2 DIE MIPS PROZESSORARCHITEKTUR 11

Zahl werden also die höherwertigen 16 Bits mit Nullen und bei einer negativen Zahl entsprechendder Codierung nach dem Zweierkomplement mit Einsen gefüllt. Einzige Ausnahme sind logischVerknüpfungen wie z.B. andi, ori und xori, bei denen die hochwertigsten Bits der Konstanteimmer mit Nullen aufgefüllt werden.

2.3.2.3 J-Typ Instruktionen

Die Abkürzung J-Typ steht für Jump-Typ und wird nur für bedingungslose Programmsprüngeverwendet. Wie in Abbildung 6 dargestellt verwendet dieses Instruktionsformat ebenfalls das 6Bit breite op Code Feld. Alle restlichen Bits der Instruktion formen eine 26-Bit breite Konstante,die einer Speicheradresse entspricht. Wie bereits im Abschnitt 2.3.1.3 erwähnt, ergibt sich dietatsächliche Sprungadresse dadurch, dass die Konstante um zwei Bit nach links geschoben wirdund um die vier hochwertigsten Bits des aktuellen Programmzählers ergänzt wird.

6 Bit 26 Bit

op addr

Abbildung 6: Instruktionsformat eines J-Typ Befehls

In Abbildung 7 ist beispielhaft der Maschinen-Code eines jal Befehls abgebildet. Der Para-meter sum im Assembler Code entspricht dabei einem Label, das während der Programmierungan die Stelle des Codes platziert wird, zu der gesprungen werden soll. Der Assembler berechnetautomatisiert, die daraus resultierende Adresskonstante und fügt sie dem Maschinen Code hinzu.

3 0x010028jal sum 000011 00 0001 0000 0000 0000 0010 1000 0x0C100028

Assember Feldwerte Binär Code Hex Code

6 Bit 6 Bit 26 Bit

op addr op addr

26 Bits

Abbildung 7: Instruktions-Code einer I-Typ Anweisungen

2.4 Pipeline Mikroarchitektur

Die MIPS32 microAptiv UP Architektur verwendet eine 5-stu�ge Pipeline zur Befehlsausführung.Im Vergleich zu einer monozyklischen Architektur wird durch das Pipelining bei moderater Stei-gerung der Leistungsaufnahme und der Hardwarekomplexität der Befehlsdurchsatz signi�kanterhöht. Die Stufen der Befehlspipeline lassen sich dabei wie folgt aufschlüsseln:

� Fetch

� Decode

� Execute

� Memory

� Writeback

Durch die Pipeline können fünf Befehle gleichzeitig bearbeitet werden, die sich in den einzelnenStufen der Pipeline be�nden. Da die einzelnen Pipelinestufen nur ein Fünftel der Gesamtkomple-xität besitzen, können Sie wesentlich schneller als ein monozyklisches System getaktet werden.

2 DIE MIPS PROZESSORARCHITEKTUR 12

Sind aktuell prozessierte Befehle von den Ergebnissen vorheriger Befehle abhängig, welche diePipeline noch nicht vollständig durchlaufen haben, wird die Bearbeitung des abhängigen Be-fehls gestoppt, bis das notwendige Ergebnis vorliegt. Um die Wartezeit zu reduzieren, gibt esdie Möglichkeit Zwischenergebnisse durch einen Bypass von einer Pipelinestufe zur nächstendurchzureichen.

IMadd

RS

$s2

$s3

+DM

RS$s0

IMand

RS

$s0

$s1

&DM

RS$t0

IMor

RS

$s4

$s0

|DM

RS$t1

IMsub

RS

$s0

$s5

-DM

RS$t2

Zyklen

1 2 3 4 5 6 7 8

add $s0, $s2, $s3

and $t0, $s0, $s1

or $t1, $s4, $s0

sub $t2, $s0, $s5

Abbildung 8: Zeitdiagramm der Befehlsverarbeitung nach dem Pipeline Ansatz

Da in Abbildung 8 dargestellte Diagramm soll den zeitlichen Ablauf der Bearbeitung von5 nachfolgenden Befehlen in der Befehlspipline visualisieren. Während des ersten Taktzyklusseswird der erste Befehl add aus dem Programmspeicher gelesen und zwischengespeichert. Im zwei-ten Taktzyklus wird der Befehl dekodiert und erkannt, dass die Operanden den Registern $s2 und$s3 entnommen werden. Die Operanden und der dekodierte Befehl werden zwischengespeichert.Zeitgleich wird der nächste Befehl and aus dem Befehlsspeicher geladen und zwischengespei-chert. Im dritten Takt wird die Addition der Registerwerte $s2 und $s3 durchgeführt und dasErgebnis und der dekodierte Befehl in der dritten Pipelinestufe zwischengespeichert. Zur gleichenZeit wird der and Befehl dekodiert und detektiert, dass die Operanden den Registern $0 und$1 entnommen werden. Da das Ergebnis des add Befehls jedoch erst im 5. Systemtakt in dasRegister $0 zurückgeschrieben wird, steht zu diesem Zeitpunkt der korrekte Wert noch nicht zurVerfügung.

Ohne weitere Maÿnahmen würde der falsche Wert des Registers $0 bei der and Operationgenutzt werden. Ein derartiger Betriebszustand, der auch als Hazard bezeichnet wird, führt danneventuell zum zwischenzeitlichen Stopp der Befehlsverarbeitung beziehungsweise zur Aktivierungvon Bypasskanälen, welche Zwischenergebnisse von einer Pipelinestufe zur nächsten durchreichen.z.B. steht das Ergebnis der add Operation, welches später in Register $s0 geschrieben wird,bereits zum dritten Taktzyklus am Ausgang der ALU zur Verfügung. Dieses Ergebnis könnte indiesem Fall in den Zwischenspeicher, der sich am Übergang zwischen der zweiten und der drittenPipelinestufe be�ndet abgelegt werden, so dass im nächsten Taktzyklus der richtige Wert von$s0 für die Durchführung der and Operation an der ALU anliegt.

Im dritten Takt wird im dargestellten Beispiel auch der nächste Befehl or aus dem Pro-grammspeicher geladen und in den Zwischenspeicher der ersten Stufe geschrieben. Bei Befehlenwie sw oder lw bei denen Daten aus dem Datenspeicher oder in den Datenspeicher geschriebenwerden, �ndet diese Operation in der 4. Pipelinestufe statt. In allen anderen Fällen werden diezwischengespeicherten ALU Ergebnisse zusammen mit der dekodierten Befehlsinformation wieauch bei den dargestellten Beispielbefehlen an die 5. Pipelinestufe weitergereicht. Im 5. Takt wird

2 DIE MIPS PROZESSORARCHITEKTUR 13

76 5

3

Inst

ructi

on

Me

mo

ry

1

AR

D2

CLK EN

PC

FP

C

4

+

CLK

01

Re

gis

ter

File

Inst

rD

25

:21

20

:16

A1

A2

A3

WD

3

RD

1

RD

2

25

:21

20

:16

15

:11

15

:0S

ign

Ext

en

d

PC

Plu

s4F

PC

Plu

s4D

+<

<2

4

RsD

RtD

Rd

D

Sig

nIm

mD

CLK

=

Bra

nch

D

PC

Src

D

Co

ntr

ol

Un

it

5:0

31

:26

Op

Fu

nct

8

9

10

RtE

Rd

E

Re

gD

est

DR

eg

De

stE

Sig

nIm

mE

Src

AE

Src

BE

ALU

Src

DA

LUS

rcE

CLK

ALU

Wri

teD

ata

E

Wri

teR

eg

E

ALU

Co

ntr

olD

ALU

Co

ntr

olE

11

12

13

14

15

Da

ta

Me

mo

ry

RD

16W

ALU

Ou

tMA W

DW

rite

Da

taM

Me

mW

rite

DM

em

Wri

teE

Me

mW

rite

M

Me

mto

Re

gD

Me

mto

Re

gE

Me

mto

Re

gM

CLK

Re

ad

Da

taW

ALU

Ou

tW

Me

mto

Re

gW

Wri

teR

eg

MW

rite

Re

gW

Re

sult

W

17

WE

3

Re

gW

rite

DR

eg

Wri

teE

Re

gW

rite

MR

eg

Wri

teW

Me

mto

Re

gD

Me

mto

Re

gE

Me

mto

Re

gM

Me

mto

Re

gW

Abbildung 9: Pipline Mikroarchitektur

2 DIE MIPS PROZESSORARCHITEKTUR 14

schlieÿlich das Ergebnis der and Operation in das Register $s0 geschrieben. In gleicher Weisedurchlaufen auch die nachfolgenden Befehle alle Stufen der Befehlspipeline.

In Abbildung 9 ist eine Blockdiagramm einer möglichen Implementation der 5 stu�gen Pi-pline Architektur abgebildet. Um in der ersten Pipelinestufe (Fetch) den nächsten Befehl ausdem Programmspeicher (1) auslesen zu können, wird die Adresse des aktuellen Befehls an denProgrammspeicher gelegt. Ein Multiplexer (2) entscheidet dabei aus welcher Quelle die Pro-grammspeicheradresse entnommen wird. Die Adresse wird entweder durch die Inkrementierungder Adresse des vorherigen Befehls über ein dediziertes Schaltwerk (3) erzeugt oder im Fall einesSprungbefehls aus der Summe der inkrementierten Adresse PCPlus4D und der 16 Bit Konstanteaus dem Code des Sprungbefehls generiert. Die 16 Bit Konstante wird zuerst um zwei Bit nachlinks geschoben (4) und dann in einem Schaltwerk (5), welches sich in der zweiten Pipelinestfufe(Decode) be�ndet, auf die aktuellen Adresse PCPlus4D aufsummiert. Durch die Nutzung eineseigenständiger Schaltwerkes (3) in der Fetch Stufe statt des ALU Rechenwerkes in der ExecuteStufe für die Berechnung der Programmspeicheradresse kann mit jedem Takt eine neue Adresseermittelt werden. Die Sprungentscheidung wird bereits in der Decode-Stufe mit einem Verglei-cher (6) geprüft und nicht erst in der Execute Stufe mit der ALU. Dadurch ist die Anzahl derZyklen, die durch den Sprung blockieren bzw. neu prozessiert werden müssen, auf ein Minimumreduziert. Da der Sprungbefehl Registerinhalte prüfen könnte, die vom Ergebnis des vorherigenBefehls in der Pipeline abhängen, besteht die Möglichkeit über die Multiplexer (7) und (8) stattden Registerdaten die ALU Ausgansdaten ALUOutM an den Vergleicher zu führen.

In der Decode Stufe wird der aus dem Programmspeicher entnommene und zwischengespei-cherte Befehl analysiert. Die Op Bits 31:26 und die Funct Bits 5:0 werden durch die Kontrollein-heit (9) ausgewertet, um den Instruktionstyp und die ausführende Operation festzustellen. BeiR-Typ Instruktionen be�nden sich in den Bits 25:21 und 20:16 die Registernummer rs und rt,welche an den Adresseingängen des Register Files (10) A1 und A2 angelegt werden, wodurch dieRegisterinhalte an den Ausgängen RD1 und RD2 bereit gestellt werden. Bei I-Typ Instruktionenbe�nden sich in den Bits 15:0 die Konstante Imm, welche unter Berücksichtigung des Vorzeichensauf 32 Bit erweitert wird und an die Execute Stufe als Signal SignImmD weitergeleitet wird.

In der Execute Stufe führt die ALU (11) die Rechenoperation aus, welche von der ControlUnit (9) über das Signal ALUControlE angefordert wird. Dabei kann die Control Unit durchden Multiplexer (12) und dem Signal ALUSrcE beein�ussen, ob für die Prozessierung eines R-Typ Befehls beide Operanden aus Registern entnommen werden oder bei einem I-Typ Befehlein Operand von der Befehlskonstante Imm festgelegt wird, welche am Signal SignImmE an-liegt. Für den Fall, dass der Befehl, welcher gerade in der Execute Stufe bearbeitet wird, vonden Ergebnissen den beiden vorherigen Befehle abhängt, die sich gerade in der Memory bzw.Writeback Stufe be�nden, besteht über die Multiplexer (12) und (13) die Möglichkeit, statt denRegsisterinhalten direkt das vorherige ALU Ergebnis ALUOutM bzw. den Datenausgang derWriteback Stufe ResultW an die Eingänge der ALU zu führen und dadurch, die Blockade derPipeline zu verhindern. Das Zielregister der Datenoperation wird von der Control Unit über dasSignal RegDestE und dem Multiplexer (15)festgelegt. Bei Speicherzugri�en wird die Adresse auseinem Registerwert und dem im Befehl festgelegten O�set in der ALU berechnet während dieabzuspeichernden Daten über das Signal WriteDataE bereitgestellt werden.

Dementsprechend liegt in der Memory-Stufe das ALU Ausgangssignal ALUOutM am Adress-port A des Datenspeichers an, während das Signal WriteDataM an den SchreibdateneingangWD geführt wird. Bei Befehlen ohne schreibenden Speicherzugri� wird das ALU AusgangssignalALUOutM einfach zur Writeback Piplinestufe durchgeschli�en. Für lesende Speicherzugri�e wirdder am Ausgang RD des Datenspeichers anliegenden adressierte Inhalt ebenfalls zur WritebackStufe geführt. Die Control Unit kann über das Signal MemWriteM bestimmen, ob das anliegende

2 DIE MIPS PROZESSORARCHITEKTUR 15

Datenwort WriteDataM entsprechenden des ausgeführten Befehls in den Speicher geschriebenwerden soll oder nicht.

In der Writeback Stufe kann die Control Unit über das Signal MemtoRegW entscheiden, obder Multiplexer (17) den ausgelesene Speicherinhalt ReadDataW oder das Ergebnis der ALUOperation ALUOutW an das Zielregister weiterreicht. Für das Abspeichern des ResultW Daten-wortes wird das Signal WriteRegW an den dritten Adresseingang des Register Files (10) geführt.Über das Signal RegWriteW löst die Control Unit den Schreibvorgang in das Register aus.

2.5 Speicherorganisation

kseg3

kseg2

kseg1

kseg0

kseg3

kseg3

dseg

kseg2

kseg1

kseg0

useg kuseg kuseg

Debug ModeKernel ModeUser ModeVirt. Adresse0xFFFF_FFFF

0xFF40_00000xFF3F_FFFF

0xFF20_00000xFF1F_FFFF

0xE000_0000

0xDFFF_FFFF

0xC000_0000

0xBFFF_FFFF

0xA000_0000

0x9FFF_FFFF

0x8000_0000

0x7FFF_FFFF

0x0000_0000

Abbildung 10: Adresskarte des virtuellen Speichers nach Betriebsmodus

Die Memory Management Unit des MIPS microAptiv UP Prozessor Cores bildet Adressenaus dem virtuellen 32-Bit Adressraum in physikalische Adressen ab, bevor eine Anfrage an dieCache Controller oder der Zugri� auf externen Speicher über die Bus Interface Unit erfolgt.Die genaue Abbildung hängt dabei vom Betriebsmodus des Prozessors ab. Es werden drei Modiunterschieden:

� User Mode wird meist für Applikationsprogramme genutzt.

� Kernel Mode wird typischerweise für das Exception Handling und Betriebssystem Funk-tionen wie den I/O Gerätezugri� genutzt.

� Debug Mode wird für die Initialisierung und die Softwareentwicklung genutzt

Der Core be�ndet sich nach einem Reset oder beim Auftritt einer Exception im Kernel Mode.Wie in 10 dargestellt, hat die Software in diesem Betriebsmodus Zugri� auf den kompletten

2 DIE MIPS PROZESSORARCHITEKTUR 16

Adressraum einschlieÿlich der Register des CP0 Coprozessors. Im User Mode ist der Zugri� nurauf einen Teil des virtuellem Adressraumes beschränkt (0x0000_0000 - 0x7FFF_FFFF) und derZugri� auf CP0 Funktionen kann untersagt sein. Im User Mode sind virtuelle Adressen im Bereich0x8000_0000 to 0xFFFF_FFFF nicht zugelassen und führen bei Zugri� zu einer Exception.

Der Debug Mode wird beim Erscheinen einer Debug Exception erreicht. Im Debug Modushat die Debug Software die gleiche Zugri�srechte wie im Kernel Modus. Zusätzlich kann imDebug Modus auf das Debug Speichersegement dseg zugegri�en werden, welcher einen Teil desKernelsegments kseg3 überlappt. Der Zugri� auf das dseg Segment kann im Debug Mode ein-und ausgeschaltet werden, um wenn nötig den vollen Zugri� auf das kseg3 Modus zu erhalten.

In diesem Projekt ist der Prozessor so kon�guriert, dass er nach dem Reset seine Arbeitim Kernel Modus aufnimmt und den Programmzähler auf die Resetadresse 0xbfc0_0000 setzt.Wie der Abbildung 10 zu entnehmen ist, be�ndet sich diese Adresse im Kernelsegment kseg1,welche weder gecached noch dynamisch über die Memory Management Unit abgebildet wird.Stattdessen gibt es eine feste Zuweisung zu einem physikalischen Adressbereich, der sich in ei-nem externen Speicher be�ndet. Dementsprechend wird das Bootprogramm aus dem externenSpeicher gelesen, wodurch berücksichtigt wird, dass weder die Caches noch die Memory Manage-ment Unit zu Beginn kon�guriert sind. Für die Berechnung der physikalischen Adresse wird dieKonstante 0xa000_0000 von der virtuellen Adresse abgezogen, wodurch das kseg1 Segment ander physikalischen Adresse 0x0000_0000 beginnt. Dementsprechend liegt die Resetadresse desProgrammzählers auf der physikalischen Adresse 0x1fc0_0000.

Virtuelle

Adresse

Physikalische

AdresseSignalname Speicher

0x1FC1_FFFC

Reset RAM

0x1FC0_0000

0xBFC1_FFFC

0xBFC0_0000

Unmapped

0xBF80_0000 0x1F80_0000 IO_LEDR

0xBF80_0004 0x1F80_0004 IO_LEDG

0xBF80_0008 0x1F80_0008 IO_SW

0xBF80_000C 0x1F80_000C IO_PB

Unmapped

0x0003_FFFC

Code/Data

RAM

0x0000_0000

0xA003_FFFC

0xA000_0000

Abbildung 11: Adresskarte des kon�gurierten physikalischen Speichers im MIPSfpga Projekt

In Abbildung 11 ist die Belegung des physikalischen Speichers im MIPSfpga Projekt darge-stellt. Ein 128kB groÿer RAM Block ist an der physikalischen Adresse 0x1fc0_0000 vorhanden,der mit dem Programm Code initialisiert wird, der nach einem Reset ausgeführt werden soll.Ein weiterer RAM Block von 256kB Gröÿe ist bei der physikalischen Adresse 0x0000_0000 vor-handen, der sowohl Code als auch Daten aufnehmen kann. Darüber hinaus existieren noch vierAdressen, welche auf GPIO Register abgebildet sind und die LEDs und Schalter des FPGA

2 DIE MIPS PROZESSORARCHITEKTUR 17

Boards ansteuern bzw. auslesen.

2.6 AHB Lite Interface

Die Verbindung der Speicher und der GPIO Register erfolgt im MIPSfpga Projekt über einAHB Lite Interface. Der Advanced High Performance Bus ist ein von ARM entworfenes o�enesInterface, welches in vielen Mikroprozessoren und in eingebetteten Systemen verwendet wird, umdie Verbindung zu peripheren Komponenten zu vereinfachen. Das AHB-Lite Protokoll ist eineabgespeckte Version der AHB Schnittstelle, welche nur einen einzigen Bus Master unterstützt.Die AHB Schnittstelle verwendet drei 32 Bit unidirektionale Busse für die Bereitstellung derAdresse HADDR[31:0] der Lesedaten HRDATA[31:0] und der Schreibdaten HWDATA[31:0]. DieKommunikation �ndet synchron zur steigenden Flanke HCLK Taktsignal statt.

HCLK

HADDR[31:0]

HWRITE

HWDATA[31:0]

Adressphase Datenphase

A B

DATA(A)

Abbildung 12: Schreibzugri� auf der AHB Schnittstelle

HCLK

HADDR[31:0]

HWRITE

HWDATA[31:0]

Adressphase Datenphase

A B

DATA(A)

Abbildung 13: Lesezugri� auf der AHB Schnittstelle

Wie in Abbildung 12 und 13 dargestellt besteht eine AHB Transaktion aus einer Adress- undeiner Datenphase. Während der Adressphase sendet der Master d.h in diesem Fall das AHBModulim Prozessor die Speicheradresse HADDR und setzt bei einem Schreibzugri� das HWRITE Signalbzw. setzt bei einem Lesezugri� das HWRITE Signal nicht. Die Adressphase beseht in der Regelnur aus einem einzigen Takt. Die Datenphase kann durch das negieren, des Signals HREADYauf mehrere Taktzyklen verlängert werden. Im Rahmen des MIPSfpga Projektes ist sowohl beieinem schreibendem als auch bei einem lesenden Speicherzugri� die Datenphase immer nur einTaktzyklus lang und das HREADY Signal wird nicht genutzt.

In Abbildung 14 ist die AHB Bus Kon�guration des MIPSfpga Projektes dargestellt. DerMaster des AHB Busses ist der Prozessors und be�ndet sich in der Bus Interface Unit. Am Bussind mit dem RAM0(Reset), RAM1 (Instructions/Data) und dem GPIO Block drei Slaves ange-schlossen. Der Master sendet den Bustakt HCLK, der dem Takt des Gesamtsystems entsprichtund die anderen Bus Signale HWRITE, HADDR und HWDATA an die Slaves. Der Bus Master

2 DIE MIPS PROZESSORARCHITEKTUR 18

MIPS

Processor

HWDATA

HADDR

HWRITE

HCLK

AHB

Master

Adress

Decoder

RAM0

(Reset)

RAM1

(D/I)GPIO

HSEL[2:0]

[0] [1] [2]

HRDATAAHB

Bus

Abbildung 14: AHB Bus Kon�guration im MIPSfpga Projekt

erhält über das Signal HRDATA die Daten eines Slaves, welche über einen Adress-Decoder undeinen Multiplexer selektiert und weitergeleitet werden.

2.7 Design Struktur

Die folgende Beschreibung der Design Hierarchie beschränkt sich auf die Top-Ebene. Zukünftigsollen alle Module aus denen der Core besteht zusammen mit ihren Funktion dokumentiertwerden.

mipsfpga_sys

m14k_top

MIPS Core

SI_CLKIn SI_Reset_N

EJ_TRST_N_probe

EJ_TDI

EJ_TDO

EJ_TMS

EJ_TCK

EJ_DINT

SI_ColdReset_N

EJTAG AHB Logic

RAM

GPIO

mipsfpga_ahb

AHB_BUS

HADDR[31:0]

HWRITE

HWDATA[31:0]

HRDATA[31:0]

IO_LEDR[17:0]

IO_LEDG[17:0]

IO_PB[4:0]

IO_Switch[4:0]

Abbildung 15: Struktur des MIPSfpga Cores auf Top Ebene

Wie in Abbildung 15 dargestellt sind auf Topebene der eigentliche Mikroprozessor Corem14k_top 1 und das Modul misfpga_ahb instanziert und miteinander verbunden. Im Modul

114k steht für die 14.000 HDL Zeilen aus denen das HDL Model des Cores besteht

2 DIE MIPS PROZESSORARCHITEKTUR 19

mipsfpga_ahb be�nden sich wie in Abbildung 14 dargestellt die Speicher und die für die An-bindung der Speicher und der GPIOs an die AHB Schnittstelle nötige Logik. Getaktet wird derProzessor mit 50MHz über das Signal SI_CLKIn. Für den synchronen bzw. asynchronen Re-set des Prozessors stehen die Signale SI_RESET_N und SI_ColdReset_N zur Verfügung. ZurProgrammierung und für das Debugging werden die Signale der EJTAG Schnittstelle genutzt.Zur Interaktion mit dem Prozessor gibt es Anschlüsse I/O Signale, die mit LEDs und Schalterbzw. Taster des FPGA Boards verbunden werden können. Eine Au�istung und Beschreibungaller Signale �ndet sich in der folgenden Tabelle.

Kategorie Name Beschreibung

System SI_RESET_N Synchrones ResetSystem SI_CLKIn 50MHz SystemtaktSystem SI_ColdReset_N Asynchrones ResetAHB HADDR[31:0] AdressbusAHB HRDATA[31:0] unidirektionaler LesedatenbusAHB HWDATA[31:0] unidirektionaler SchreibdatenbusAHB HWRITE Steuerung Schreib-/Lesezugri�I/O IO_SWITCH[17:0] Schalter SW[15:0]I/O IO_PB[4:0] Pushbuttons {BTNU,BTND,BTNL,BTNR}I/O IO_LEDR[17:0] LED[15:0]I/O IO_LEDG[8:0] Werden nicht verwendetEJTAG EJ_TRST_N_PROBE Test Reset JB[7]EJTAG EJ_TDI Test Data In JB[2]EJTAG EJ_TDO Test Data Out JB[3]EJTAG EJ_TMS Test Mode Select JB[1]EJTAG EJ_TCK Test Clock JB[4]EJTAG EJ_DINT Debug Interrupt Request GND

Tabelle 7: Schnittstellen des MIPSfpga Modelles

3 HDL SIMULATION 20

3 HDL Simulation

Für die Simulation des MIPSfgpa Modells mit einem Digitalsimulator2 wird eine Testbenchzur Stimulation des Modells und ein Testprogramm zur Ausführung während der Simulationbenötigt. Im MIPSfpga wird eine folgende Testbench zur Verfügung gestellt, die im folgendenauszugsweise vorgestellt wird.

1 i n i t i a l2 begin3 SI_ClkIn = 0 ;4 EJ_TRST_N_probe = 0 ;5 EJ_TDI = 0 ;6 EJ_TMS = 0 ;7 EJ_TCK = 0 ;8 EJ_DINT = 0 ;9 SI_ColdReset_N = 1 ;1011 f o r e v e r12 #50 SI_ClkIn = ~ SI_ClkIn ;13 end1415 i n i t i a l16 begin17 SI_Reset_N <= 0 ;18 repeat (100) @( posedge SI_ClkIn ) ;19 SI_Reset_N <= 1 ;20 repeat (1000) @( posedge SI_ClkIn ) ;21 $stop ;22 end

Im ersten Initial Block werden das Taktsignal und die Signale der EJTAG Schnittstelle aufNull initialisiert und ein Clocksignal mit 100 Zeitschritten pro Periode generiert. Bei der einge-stellten Zeiteinheit von 50ps entspricht das einer Periodendauer von 5ns und dementsprechendeinem Takt von 200MHz. Im zweiten initial Block wird der Core für die ersten 100 Clockzy-klen resettet. Anschlieÿend wird das Reset zurückgenommen und die Simulation für weitere 1000Clockzyklen laufen gelassen und dann mit $stop unterbrochen. Während dieser Zeit wird dasProgramm ausgeführt, welches sich im Resetspeicher RAM0 be�ndet. Dieses Programm wirdüber die Initialisierungsdatei ram_reset_init.txt zu Beginn der Simulation in den ResetspeicherRAM0 geladen. Zeitgleich wird der zweite Speicher RAM1, der sowohl Daten als auch Program-me beinhalten kann, mit der Datei ram_program_init.txt initialisiert. Beide Dateien müssensich im gleichen Verzeichnis ./MIPSfpga/rtl_up wie der HDL Code des Cores be�nden, um indie Simulation eingebunden zu werden. Wie diese Dateien erzeugt werden können, wird in Ab-schnitt erläutert. In der folgenden Simulation wird ein Programm verwendet, dass einen Variableinkrementiert und den aktuellen Variablenwert binär an den LEDs des FPGA Boards anzeigt.

Der Inhalt der Datei ram_reset_init.txt hat dabei folgendes Aussehen:

1 24090001 // bfc00000 : addiu $9 , $0 , 12 3 c08bf80 // bfc00004 : l u i $8 , 0 xbf803 ad090000 // bfc00008 : L1 : sw $9 , 0( $8 )4 25290001 // bfc0000c : addiu $9 , $9 , 15 3 c050026 // bfc00010 : de lay : l u i $5 , 0x0266 34 a525a0 // bfc00014 : o r i $5 , $5 , 0x25a07 00003020 // bfc00018 : add $6 , $0 , $08 00 a63822 // bfc0001c : L2 : sub $7 , $5 , $6

2Simuliert wurde mit Questasim 10.5c_4

3 HDL SIMULATION 21

9 20 c60001 // bfc00020 : addi $6 , $6 , 110 1 c e 0 f f f d // bfc00024 : bgtz $7 , L211 00000000 // bfc00028 : nop12 1000 f f f 6 // bfc0002c : beq $0 , $0 , L113 00000000 // bfc00030 : nop

In der ersten Spalte der Datei be�ndet sich der Maschinencode der auszuführenden Befehle.Die zweite Adresse entspricht der virtuellen Adresse an der die betre�enden Befehl abgelegtwerden. Wie im Abschnitt 2.5 beschrieben, entspricht die Adresse 0xbfc0_0000 dem Resetvektorim Kernel Segmentes 1 an der das Startprogramm beginnen muss. In den folgenden Spaltenbe�ndet sich die Assemblerdarstellung der Maschinenbefehle. In der ersten Zeile wird der Wertdes Registers $9 inkrementiert. Danach wird das höherwertige 16 Bit Teilwort der Speicheradresse0xbf80_0000, die zu dem LED Register gehört, in das Register $8 geschrieben. Die unteren16 Bit des Registers $8 bleiben auf Null gesetzt, so dass sich in diesem Register tatsächlichdie Adresse des LED Registers be�ndet. Der Inhalt des Registers $9 wird ohne O�set in dieSpeicherstelle mit der Adresse, welche sich im Register %9 be�ndet, abgelegt. In diesem Momentwird der aktuelle Wert des Registerinhalts an den LEDS des FPGA Boards eingeblendet. Umden Inkrementierungsvorgang für das menschliche Auge sichtbar zu machen, wird jetzt eineVerzögerungsschleife durchlaufen.

Hierfür werden in die höherwertigen 16 Bit des Registers $5 der Zahlenwert 0x0260 und indie niedererwertigen 16 Bit der Wert 0x25a0 geschrieben, so dass sich insgesamt das Datenwort0x0260_25a0 ergibt. Nachdem das Register $6 auf Null initialisiert wird, tritt das Programmin die eigentliche Verzögerungsschleife ein. Von dem Registerwert $5 wird der Registerwert $6abgezogen und in das Register $7 geschrieben. Anschlieÿend wird der Wert des Registers $6inkrementiert und geprüft, ob das Ergebnis der Subtraktion d.h. der Wert im Register gröÿerNull ist, was so lange der Fall sein wird, wie der Registerwert $6 kleiner als der Registerwert $5sein wird. Solange dies zutri�t springt das Programm an die Sprungmarke L2 und durchläuftweiter die Verzögerungsschleife. Nachdem die Verzögerungsschleife durchlaufen ist, kann der anden LEDs dargestellte Zählerwert wieder inkrementiert werden, hierfür springt das Programmimmer an die Stelle mit der Sprungmarke L1 und setzt die Funktion endlos weiter.

Für den Start der Simulation mit Questa- oder Modelsim existiert das simMIPSfpga.tclSkript, welches innerhalb des Digitalsimulators ausgeführt werden kann und im folgenden eben-falls vorgestellt wird. Die Initialisierung des Simulators und die Erstellung des Simulationspro-jektes wird als bekannt voraus gesetzt.

1 v log . . / . . / rtl_up /* . v +i n c d i r + . . / . . / rtl_up/2 vsim −novopt tes tbench3 do wave . do4 run −a l l

Zuerst werden alle Dateien im Verzeichnis rtl_up mit dem Befehl vlog kompiliert. Anschlie-ÿend wird die Simulation mit dem Befehl vsim gestartet. Der Parameter testbench entsprichtdabei dem Modulnamen den oben erläuterten Testumgebung. Abweichend zu dem mit demMIPSfpga Tutorial mitgelieferten Skript musss zusätzlich noch die Option -nvopt gesetzt wer-den, wenn die Signale auf allen Hierachiebenen des Designs gespeichert und dargestellt werdensollen. Abschlieÿend wird die mitgelieferte Datei wave.do ausgeführt, welche dafür sorgt, dass dieSignale auf der Topebene des Designs in den Waveform Viewer aufgenommen werden sollen. DasSkript wird mit source simMIPSfpga.tcl ausgeführt und die Simulation mit run -all gestartet.

Wie in Abbildung 16 dargestellt wird der Reset bei etwa 1.000.000 ps zurückgenommenund die Busadresse HADDR auf den Resetvektor 0x1fc0_0000 gesetzt. Einen Taktzyklus späterwird der Maschinencode des ersten Befehl 0x2409_0001 aus dem Resetspeicher auf den Lesebus

3 HDL SIMULATION 22

Abbildung 16: Simulation des MIPSfpga Projetkes mit LED Beispielprogramm

3 HDL SIMULATION 23

HRDATA geschrieben (addiu $9, $0, 1). Vier Takte später wird der Maschinencode des nächstenBefehls von der Adresse 0x1fc0_0004 angefordert und der Maschinencode 0x3c08_bf80 (lui $8,0xbf80) erscheint auf dem Lesebus. Interessant zu sehen ist, dass nicht zu jedem Takt sondernnur alle 5 Takte ein Befehl aus dem Speicher gelesen wird. Dies ist dadurch begründet, dassnach dem Reset die Caches noch nicht initialisiert sind und jeder Speicherzugri� direkt auf denexternen Speicher erfolgt. Die 5 benötigten Zyklen schlüsseln sich wie folgt auf:

� Ein Zyklus um festzustellen, dass die Daten nicht im Cache vorhanden sind

� Ein Zyklus um eine Anfrage an die Bus Interace Unit zu stellen

� Ein Zyklus in der die Bus Interface Unit einen Lesezugri� auf dem AHB Bus vollzieht

� Ein Zyklus wird benötigt um die Daten aus dem externen Speicher auf den AHB Bus zulegen

� Ein Zyklus um die Daten vom AHB Bus in das betre�ende Register zu schreiben.

Als nächste wird der Befehl 0xad09_0000(sw $9, 0($8) ), der sich an der physikalischen Adres-se 0x1fc0_0008 be�ndet aus dem Speicher geholt. Dieser Befehl speichert den aktuellen Wert desLED Zählers an die virtuelle Adresse 0xbf80_0000 (physikalische Adresse 0x1f80_0000). Bevorjedoch der Zugri� des Speicherbefehls erfolgt, wird bereits der nächste Befehl 0x2529_0001 (ad-diu $9, $9, 1 ) von der Adresse 0x1fc0_000c gelesen. Erst anschlieÿend wird die Adresse HADDRauf den Wert des Speicherzugri�es 0x1f80_0000 aktualisiert und für den Schreibzugri� das Si-gnal HWRITE gesetzt. Einen Takt später erscheint das Datum 0x0000_0001 auf den SchreibbusHWDATA der in das LED Register geschrieben werden soll. Als nächstes entnimmt der Prozes-sor den Maschinencode 0x1000_�fd and 0x0000_0000 Befehls, welche sich an den physikalischenAdressen 0x1fc0_0010 und 0x1fc0_0014 be�nden und springt dann auf den sw Befehl an derAdresse 0x1fc0_0008 zurück. Wenn man dem Simulationsverlauf folgt, kann man erkennen, dassder Prozessor immer wieder Befehle aus dem Adressraum 0x1fc0_0008-0x1fc0_0014 liest undinkrementierende Werte auf die Speicheradresse 0x1f80_0000 schreibt.

4 FPGA IMPLEMENTATION 24

4 FPGA Implementation

Das MIPSfpga Model wurde unter Verwendung der Entwurfssoftware Vivado 2017.4 auf einemNexus4 Board implementiert, auf dem sich ein Xilinx Artix-7 (xc7a100tcsg324-1) FPGA Bau-stein be�ndet. Für die Implementierung wird ein Wrapper Modul benötigt, dass die Anpassungzwischen der Schnittstelle des Prozessors und den Komponenten des FPGA durchführt. Darüberhinaus muss an Hand eines Constraints Files (xdc) das Mapping zwischen den Ports des Wrap-per Moduls und den passenden Pins des FPGAs erfolgen, so dass der Prozessor mit den LEDs,Schaltern und Buttons des Boards verbunden ist. Sowohl das Wrapper Modul als auch die xdcDatei ist MIPSfpga Projekt mitgeliefert und müssen während der Initialisierung des Vivado Pro-jektes eingebunden werden. Darüber hinaus wird für die Erzeugung des 50MHz Taktes aus dem100MHz Oszillators des Nexus Boards die Einbindung eine Clock Management IP in das VivadoProjekt notwendig. Die Erstellung des Projektes und die Implementierungsschritte werden imFolgenden in Tutorialform erläutert.

Nach dem Start der Vivado Entwicklungsumgebung wird durch den Menüpunkt �File ->New Project� ein neues Entwicklungsprojekt begonnen. Der Projekt Wizard durchläuft mehrereSchritte. Zu Beginn wird der Name und das Verzeichnis des Projektes festgelegt. Im nächstenSchritt wird der Projekt Typ �RTL Project� festgelegt. Anschlieÿend werden die HDL Sour-cen selektiert. In diesem Schritt werden zuerst ALLE Dateien aus dem rtl_up Verzeichnis desMIPSfpga Paktes selektiert. Besonders wichtig ist es, dass neben den Verilog Dateien mit der En-dung .v auch die Include Dateien mit der Endung .vh und auch die Speicherinitialisierungsdatei-en ram_reset_init.txt und ram_program_init.txt dem Projekten in diesem Schritt hinzugefügtwerden.

Abbildung 17: Selektion der RTL Sourcen

Wie in Abbildung 17 dargestellt, ist es dafür notwendig, dass diese Dateien bei der Dateise-lektion sichtbar sind, was durch die Einstellung des Datei�lters �Files of Types� auf �All Files�möglich wird. Neben den Dateien aus dem Verzeichnis rtl_up wird noch das Wrapper Modulmipsfpga_nexys4.v aus dem Verzeichnis Nexys4 benötigt und muss ebenfalls im gleichen Schrittzu den Sourcen hinzugefügt werden. Im nächsten Schritt können dem Projekt Constraint Fi-les zugeordnet werden. An dieser Stelle wird die Datei mipsfpga_nexys4.xdc aus dem Nexys4Verzeichnis selektiert und in das Projekt übertragen.

4 FPGA IMPLEMENTATION 25

Abbildung 18: Selektion des Artix-7 FPGA Baussteins

Zuletzt muss noch der verwendete FPGA Baustein selektiert werden. Das Nexys4 Board istmit einem Artix7 Baustein mit der Bezeichnung xc7a100tcsg324-1 bestückt. Wie in Abbildung18 zu sehen, kann diese Bezeichnung in das �Search� Feld der entsprechenden Maske eingetragenwerden, um die Suche und die Selektion des Bauteils zu vereinfachen. Nach der Initialisierungdes Projektes muss das Modul mipsfpga_nexys4 als Top Zelle selektiert werden, was durchRechtsklick und die Selektion des Menüpunktes �Set as Top� geschieht. Die Wrappermodule füralternative FPGAs mipsfpga_nexys4_ddr oder mipsfpga_de2_115 können bei Bedarf aus demProjekt entfernt werden, was durch Rechtsklick auf die entsprechende Datei und der Selektiondes Menüpunktes �Remove File from Project� geschieht.

Nachdem alle Sourcen und das Constraint File in das Projekt eingefügt worden sind, mussnoch die PLL Instanz generiert werden. Wie in Abbildung 19 zu sehen ist, muss hierfür im MenüWindow der IP Catalog aufgerufen werden. Dort be�ndet sich unter der Rubrik �FPGA Featuresand Designs�-> Clocking -> �Clocking Wizard�. Durch Doppelklick startet das Kon�gurations-fensters des IP Blocks

Die Kon�guration geschieht in zwei Schritten. Wie in Abbildung 20 wird im ersten Schritt derPrimitive PLL selektiert und die Frequenz der Primary Clock auf 100 MHz gestellt. Der zweiteKon�gurationsschritt erfolgt auf dem �Output Clock� Reiter, der in Abbildung 21 dargestellt ist.Dort wird die Frequenz des clk_out1 Taktsignals auf 50 MHz gesetzt und alle optionalen Outputs

4 FPGA IMPLEMENTATION 26

Abbildung 19: Selektion des Clocking Wizard Kon�gurators

Abbildung 20: Erster PLL Kon�gurationsschritt

wie Lock und Reset deselektiert. Die Kon�guration wird mit dem OK Button abgeschlossen undist erfolgreich verlaufen, wenn die Clocking Wizward Instanz clk_wiz_0 in der Projekthierarchieunter dem Modul mipsfpga_nexys4 erscheint. Falls eine erneute Kon�guration des Clockmodulsnotwendig sein sollte, kann durch Doppelklick auf die clk_wiz_0 Instanz in der Projekthierarchie

4 FPGA IMPLEMENTATION 27

das Kon�gurationsfenster von Neuem geö�net werden.

Abbildung 21: Zweiter PLL Kon�gurationsschritt

Der Implementierungsvorgang wird in vier Schritten durchlaufen. Zuerst wird die Syntheseüber �Synthesis->Run Synthesis� gestartet. Falls die Initialisierungsdateien für die RAM Bau-steine nicht in das Projekt eingebunden worden sind, erscheint an dieser Stelle eine Warnung.Die Dateien müssen dann dem Projekt hinzugefügt werden und der Synthesevorgang wieder vonNeuem gestartet werden. Anschlieÿend wird der Place & Route Schritt durch �Implementation->Run Implementation� initiiert. Vor der eigentlichen Kon�guration des FPGAs muss noch dieKon�gurationsdatei über �Program and Debug -> Generate Bitsream� erzeugt werden. Spätes-tens jetzt muss das Nexus4 Board an einen USB Port des verwendeten PCs angeschlossen undeingeschaltet werden. Die Verbindung zum Board wird über �Program and Debug -> Open Tar-get -> Auto Connect� etabliert. Mit �Program and Debug -> Program Device� wird das BitFile auf das FPGA geschrieben. Wenn die FPGA Kon�guration abgeschlossen ist, leuchtet dieDONE LED (LD21) des Boards. Drückt man den CPU_RESET Taster (C12) beginnt die Aus-führung des Programms und der inkrementierende Registerwert wir kontinuierlich an den LEDSangezeigt.

5 PROGRAMMIERUNG 28

5 Programmierung

Die Programmierung erfolgt ohne spezielle Entwicklungsumgebung basierend auf Textdateienund der GNU Toolchain. Ein im MIPSfpga Projekt mitgeliefertes Beispielprogramm, dass imRahmen dieser Studie leicht modi�ziert worden ist, wird im Folgenden erläutert. Das Programmhat drei Betriebsmodi, die sich wie folgt aufschlüsseln. Wenn kein Schalter geschlossen ist, wirdeine Gruppe von vier 4 Bits in einem Register dauerhaft von links nach rechts geschoben undan den LEDs des Boards angezeigt. Wenn alle LEDS aus sind, werden wieder die 4 LEDs ganzlinks eingeschaltet und der Vorgang beginnt von Neuem. Ist der Schalter SW4 geschlossen, wirdein Zähler inkrementiert und der Zählerstand an den LEDS angezeigt. Ist der Schalter SW3geschlossen, wird der Zählerstand dekrementiert. Ist der Schalter SW2 geschlossen, blinken alleLEDs. Zusätzlich wurde im Rahmen der Studie noch ein �Knight-Rider� Modus in das ursprüng-liche mitgelieferte Programm eingefügt. Ist der Schalter SW1 geschlossen, wird ein Bit zuerstvon Links nach Rechts geschoben, bis die 16. LED eingeschaltet wird. Dann kehrt sich der Schie-bevorgang um und das Bit wird von rechts nach links geschoben bis die 1. LED eingeschaltetworden ist und sich die Schieberichtung wieder umkehrt und der Vorgang so von Neuem beginnt.

1 #de f i n e in l ine_assembly ( ) asm( " o r i $0 , $0 , 0x1234" )23 void de lay ( ) ;45 i n t main ( ) {6 v o l a t i l e i n t *IO_LEDR = ( in t *)0 xbf800000 ;7 // v o l a t i l e i n t *IO_PUSHBUTTONS = ( in t *)0 xbf80000c ;8 v o l a t i l e i n t *IO_PUSHBUTTONS = ( in t *)0 xbf800008 ;9 v o l a t i l e unsigned i n t pushbutton , count = 0 , d=0;1011 whi le (1 ) {12 pushbutton = *IO_PUSHBUTTONS;1314 switch ( pushbutton ) {15 case 0x8 : count++; break ;16 case 0x4 : count−−; break ;17 case 0x2 :18 i f ( count==0) count = ~count ;19 e l s e count = 0 ;20 break ;21 case 0x1 :22 i f (d==0)23 i f ( count < 0x8000 )24 count = count << 1 ;25 e l s e26 {27 d=1;28 count = count >> 1 ;29 }30 e l s e31 i f ( count > 1)32 count = count >> 1 ;33 e l s e34 {35 d=0;36 count = count << 1 ;37 }38 break ;39 d e f au l t : i f ( count==0) count = 0 xf ;

5 PROGRAMMIERUNG 29

40 e l s e count = count << 1 ;41 }4243 *IO_LEDR = count ; // wr i t e to red LEDs44 de lay ( ) ;45 in l ine_assembly ( ) ;46 }47 return 0 ;48 }4950 void de lay ( ) {51 v o l a t i l e unsigned i n t j ;5253 f o r ( j = 0 ; j < (1000000) ; j++) ; // de lay54 }5556 void _mips_handle_exception ( void * ctx , i n t reason ) {57 v o l a t i l e i n t *IO_LEDR = ( in t *)0 xbf800000 ;5859 *IO_LEDR = 0x8001 ; // Display 0x8001 on LEDs to i nd i c a t e e r r o r s t a t e60 whi le (1 ) ;61 }

Zu Beginn der Main Funktion, werden die virtuellen Adressen des LED und KippschalterRegisters den Pointer *IO_LED bzw. *IO_PUSHBUTTONS zugewiesen. Aus der auskommen-tierten Zeile 7 wird ersichtlich, dass im ursprünglichen Programm die Taster des Boards zurEingabe verwendet wurden. In der while Schleife wird zunächst der Zustand der Kippschalterabgefragt. Anschlieÿend wird, je nach geschlossenem Schalter einer der vier oben beschriebenenModi ausgeführt, in dem das Programm in dem entsprechenden Zweig der switch Anweisungspringt. Dort wird eine Variable count je nach Modus inkrementiert, dekrementiert oder gescho-ben. Der aktualisierte Wert der Variablen count wird in Zeile 43 in das LED Register geschrieben.Anschlieÿend wird die Unterfunktion delay() aufgerufen, die den Zweck verfolgt, die Änderungender LEDs so weit zu verlangsamen, dass sie für das menschliche Auge sichtbar werden. Hierfürwird in dieser Funktion einfach eine Variable von 0 bis 106 inkrementiert. Zum Schluss wird eineInline Assembleroperation ausgeführt, die eine Oer-Operation zwischen eine Konstante und demNullregister $0 durchführt. Das Ergebnis dieser Operation wird wieder dem Register $0 zugewie-sen und geht dadurch verloren. Der genaue Hintergrund für die Verwendung dieses Befehls istmomentan noch nicht vollständig geklärt. Wahrscheinlich handelt es sich einfach um eine weitereVerzögerung.

Neben dem C Programm existiert im MIPSfpga Projekt auch ein Beispiel für ein Assem-blerprogramm, welches ebenfalls im Rahmen dieser Studie leicht modi�ziert worden ist. DasProgramm liest die Schalter und Tasterstellung ein und stellt diese an den grünen bzw. denroten LEDs dar. Da das Nexys4 Board nur über einen Satz grüne LEDs verfügt, wurde dasAssemblerprogramm so verändert, dass die Taster- und Schalterstellung als Bitkombination in-terpretiert werden, welche miteinander xor verknüpft werden. Das Ergebnis der xor Verknüpfungwird dann an den LEDs angezeigt.

1 . g l ob l main23 main :4 l u i $8 , 0 xbf80 #LED adre s s5 addiu $13 , $8 , 8 # $13 = SW address o f f s e t6 addiu $14 , $8 , 0xc # $14 = PB address o f f s e t7 readIO :

5 PROGRAMMIERUNG 30

8 lw $10 , 0( $13 ) # read sw i t che s : sw = SW values9 lw $11 , 0( $14 ) # read pushbuttons : pb = PB va lues10 xor $9 , $10 , $11 # xor sw i t che s and pushbuttons11 sw $9 , 0( $8 ) # wr i t e switch va lue s to red LEDs12 beq $0 , $0 , readIO # repeat13 nop # branch de lay s l o t

Zu Beginn wird das hochwertige Halbwort 0xbf0 der LED Registeradresse in das Register $8geschrieben. Da das Register beim Reset mit Nullen vorinitialisiert worden ist, steht im Register$8 anschlieÿend der Wert 0xbf80_0000, was der kompletten LED Registeradresse entspricht. InZeile 5 und 6 wird durch Addition der Konstanten 8 und 12 auf den Wert von Register $13 und $14die Schalterregisteradresse 0xbf80_0008 bzw. die Tasterregisteradresse 0xbf90_000c gespeichert.In Zeile 8 und 9 werden das Schalterregister und das Tasterregister ausgelesen und die Register$10 und $11 geschrieben. Auf diese Registerwerte wird in Ziele 10 eine xor Operation durchgeführtund das Ergebnis der xor Operation wird in das LED Register geschrieben und damit die LEDszum Leuchten gebracht. Anschlieÿend springt das Programm an die Marke readIO zurück undliest von Neuem die Werte der Schalter und Taster aus.

5.1 Kompilier- und Assembliervorgang

Für die Softwareprogrammierung in C und Assembler wird die Entwicklungsumgebung Codesca-pe MIPS SDK Essentials genutzt. Zur Installation der Software steht ein Installationsprogramm(OpenOCD-0.9.3-Installer.exe) zur Verfügung, das zeitgleich auch die Installation der OpenOCDSoftware für den Programm-Upload durchführt. Für die Kompilierung bzw. Assemblierung soll-ten zusätzlich noch die Assemblerprogramme, welche den Bootloader bilden und das beispielhafteMake�le aus dem Verzeichnis Codescapce\ExamplePrograms\CExample des MIPSfpga Projek-tes in das Verzeichnis kopiert werden, in dem sich die zu kompilierende bzw. assemblierendeDatei main.c bzw. main.S be�ndet. Der Bootloader hat die Aufgabe den Prozessor zu initiali-sieren und insbesondere die Caches für den Programm- und den Datenspeicher zu springen. Fürdie Kompilierung ist nur die Ausführung des Befehls make nötig. Entsprechend den Einträgendes Make�les wird das Programm dann prozessiert und bei Fehlerfreiheit mit dem Bootloaderverlinkt und in die FPGA_Ram.elf (Executable and Link Format) Datei als maschinenlesba-rer Code geschrieben. Diese Datei kann dann, wie in Kapitel 6 beschrieben, in den Prozessorhochgeladen werden.

5.2 Erstellung von Speicherinitialisierungsdateien

Für die Simulation von Programmen mit Questasim und die FPGA Implementierung werden dieDateien Speicherinitialisierungsdateien ram_reset_init.txt und ram_program_init.txt benötigt.Für die Erstellung dieser Dateien existiert das Skript createMem�les.bat im MIPSfpga Projektund zwar im Verzeichnis \Codescape\ExamplePrograms\Scripts. Dieses Skript muss immer ausdem Scripts Verzeichnis gestartet werden. Der einzige Parameter entspricht dem Pfad auf dasVerzeichnis in dem sich der Source Code be�ndet. Da das Skript den Source Code assembliertbzw. kompiliert, muss in diesem Verzeichnis auch ein Make�le und eventueller Boot Code vor-handen sein. Das Skript erstellt das Unterverzeichnis MemoryFiles im Verzeichnis, in dem sichauch der Source Code be�ndet und kopiert die generierten Dateien dort hin. Dieser Vorgangkann je nach Rechenleistung einige Minuten in Anspruch nehmen.

6 EJTAG PROGRAMM UPLOAD & DEBUG 31

6 EJTAG Programm Upload & Debug

Programme können in die Speicher des Prozessors durch die init Dateien ram_reset_init.txtund ram_program_init.txt geschrieben werden. Währen der Ausführung eines Resets werdendie Speicher des Mikroprozessors mit den Inhalten dieser Dateien initialisiert. Da die Init Da-teien während des Synthesevorgangs berücksichtigt werden, müssen sie zu diesem Zeitpunktauch zur Verfügung stehen und können dann im Nachhinein auch nicht mehr verändert werden.Soll das Programm aktualisiert werden, müssen neue init Dateien erzeugt und der Implemen-tierungsvorgang wiederholt werden. Diese Vorgehensweise ist jedoch nicht praktikabel, da dieImplementierung unter Umständen mehrere Stunden dauern kann.

Abbildung 22: Anschluss des Busblasters an das Nexus Board

Eine Alternative Möglichkeit die Speicher des Prozessors zu beschreiben ist die Nutzung derEJTAG Schnittstelle. Hierfür wird ein zusätzliches Hardwaremodul der sogenannte Busblasterbenötigt, welcher prinzipiell einem USB zu JTAG Adapter entspricht. Wie in Abbildung 22dargestellt, wird der Busblaster einerseits per Flachbandkabel an den PMOD Stecker JB desNexus4 Boards und andererseits per USB Kabel an den PC angeschlossen. Falls noch nichtgeschehen, muss die Entwicklungsumgebung Codescape MIPS SDK Essentials, welche eine Cross-

6 EJTAG PROGRAMM UPLOAD & DEBUG 32

Compiler Umgebung für MIPS Systeme basierend auf GNU Tools darstellt und die OpenOCDSoftware installiert werden. OpenOCD steht für Open On-Chip Debugger und ist ein Deamon-Prozess, welcher auf dem PC läuft von dem aus das Mikroprozessorsystem aus debugged undkon�guriert werden soll. Die OpenOCD Software nutzt Hardware wie z.B. den Busblaster, umeine Verbindung zum Prü�ing aufzunehmen, mit dem Ziel Programme in den Speicher zu laden,die Programmausführung zu prüfen, den Prozessorzustand zu überwachen und gegebenenfallsden Prozessor zu initialisieren. Der Nutzer kann entweder über die Kommandozeile Ein�uss aufdie Debug-Funktionalität neben oder eine Verbindung zu einem GDB (GNU Debugger) Serveretablieren, um die umfangreiche GNU Debugfunktionalitäten in Anspruch nehmen zu können.

Für die kombinierte Installation beider Tools steht im Verzeichnis Codescape des MIPSfpgaProjektes der Installer OpenOCD-0.9.3-Installer.exe zur Verfügung. Vor der Etablierung der Ver-bindung müssen noch die Treiber des Busblasters installiert werden, was sich nach der Installationdes kombinierten Codescape/OpenOCD Softwarepaketes durch den Installer zadig_2.1.1.exe imVerzeichnis C:\Programme\OpenOCD\durchführen lässt.

Nach der Installation der Software und der Treiber kann jetzt die Verbindung zum FPGABoard über den Busblaster aufgebaut werden. Zuerst wird der OpenOCD Server gestartet. Da-für wechselt man in das Verzeichnis, in dem sich die Kon�gurationsdatei openocd.cfg be�ndet,um boardspezi�sche Kon�gurationen einzubinden. Eine beispielhafte openocd.cfg Datei liegt imVerzeichnis Codescape\ExamplePrograms\Scripts\Nexys4\. Der OpenOCD Server startet durchden Befehl openocd-0.9.2.exe, den man in einer dedizierten Console (cmd.exe) unter Nutzung desvollständigen Installationspfades ausführt. In einer weiteren Console wird der GNU Debuger mitdem Befehl mips-mti-elf-gbd (ohne .exe)gestartet. In dieser Konsole kann durch die folgendengdb Befehle das Programm in den Prozessor hochgeladen werden:

1 ta r g e t remote l o c a l h o s t :3333 //Verbindung zum Port 3333 des OpenOCD Serve r s2 s e t endian l i t t l e //Der Core hat e ine L i t t l e−Endian Arch i tektur3 monitor r e s e t ha l t // Stoppt den Proz e s s o rb e t r i eb4 FILE xyz . e l f //Bestimmt d i e hochzuladende Programmdatei5 load //Lädt das Programm hoch6 monitor r e s e t run // S ta r t e t den Pro z e s s o rb e t r i eb

Alternativ können die gdb Befehle auch in eine Skriptdatei geschrieben werden, welche beimStart von GDB als Parameter übergeben wird (mips-mti-elf-gbd -x script). Statt der Bestimmungder Programmdatei in Zeile 4 des Skriptes, kann der Dateiname auch als Parameter übergebenwerden (mips-mti-elf-gbd -q xyz.elf -x script). Programme müssen für den Upload im ELF (Exe-cutable and Link) Format vorliegen und können, so wie in Kapitel 5 beschrieben, erstellt werdenkönnnen. Neben dem Programm-Upload gibt es noch weitere nützlich Möglichkeiten zum De-bugging, die in der nächsten Tabelle auszugsweise zusammengefasst werden.

6 EJTAG PROGRAMM UPLOAD & DEBUG 33

Befehl Beschreibung

monitor reset halt Reset und Stop des Prozessorsmonitor reset on Reset und Start des Prozessorsbreak main Setzt einen Breakpoint bei der Main Funktionbreak *0x80000848 Setzt einen Breakpoint bei der Programmspeicheradresse 0x80000848info breakpoint Listet alle Breakpoints aufcontinue Setzt die Ausführung bis zum nächsten Breakpoint fort.print count Gibt den Wert der Variable count ausprint /x count Gibt den Wert der Variable count in Hexadezimaldarstellung ausprint /x &count Gibt die Adresse der Variable count in Hexadezimaldarstellung ausinfo registers Gibt den Wert aller Register ausinfo registers v1 Gibt den Wert des Registers v1 ausstepi Führt eine einzige Instruktion ausdelete 1 Löschen des ersten Breakpints (info breakpoint gibt Nummern aus)

Tabelle 8: Nützliche GDB Debugging Befehle