Upload
phungnga
View
221
Download
0
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 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