Σειρά Ασκήσεων 8:
Συμπλήρωση της Σχεδίασης του Επεξεργαστή
Προθεσμία έως Τετάρτη 2 Μαΐου (βδομάδα 11)
Ασκηση 8.1: Προσθήκη των Εντολών που λείπουν
Στην 6η και 7η σειρά ασκήσεων δεν είχαμε περιλάβει
μερικές από τις εντολές που είχαμε μελετήσει στο κεφάλαιο 3.
Τροποποιείστε το datapath σας και το κύκλωμα ελέγχου σας
γιά να μπορεί ο επεξεργαστής σας να εκτελεί και αυτές
--βάλτε τα αλλαγμένα modules σας
στα αρχεία "datapath8.v" και "control8.v".
Ακολουθεί ο κατάλογός των εντολών που πρέπει να προστεθούν,
με μερικά σχόλια γιά καθεμία.
Τα op-codes και funct-codes των εντολών του MIPS
φαίνονται στη σελίδα 153 ή στην A-54 του βιβλίου.
-
addi, slti:
Οι εντολές αυτές μοιάζουν με τις add και slt,
αλλά ο δεύτερος τελεστέος τους είναι το Immx και όχι ο καταχωρητής B.
Επίσης, καταχωρητής προορισμού είναι ο rt και όχι ο rd.
Αρα, θα χρειαστούν αλλαγές στο κύκλωμα ελέγχου
γιά να μπορεί να τις εκτελεί.
Αν επιμείνετε να έχετε μόνο σήματα τύπου Moore,
θα χρειαστούν νέες καταστάσεις,
γιατί ο τρίτος και ο τέταρτος κύκλος της εκτέλεσης
διαφέρουν από τις εντολές ALU με format τύπου R.
Πιό απλή θα είναι η υλοποίηση με σήματα Mealy,
αλλά προσέξτε ότι δεν σας αρκούν πλέον το state και το funct
--χρειάζεστε και το op.
-
lui:
Η εντολή lui (load upper immediate)
χρησιμοποιείται γιά να φέρει μιά αυθαίρετη 16μπιτη σταθερά
στο MS μέρος ενός καταχωρητή,
και περιγράφεται στη σελίδα 146 του βιβλίου.
Δεν είναι εντολή μνήμης (παρά το όνομα "load")
--είναι έντολή λογικής/ολίσθησης με format τύπου I.
γιά να την υλοποιήσετε πρέπει να προσθέσετε στο datapath
ένα δρόμο που να μπορεί να φέρει το Imm16
στο περισσότερο σημαντικό (MS) ήμισυ μιάς λέξης.
Ο δρόμος αυτός μπορεί να περνάει από την ALU ή να την παρακάμπτει.
Φυσικά, χρειάζονται και οι αντίστοιχες προσθήκες στον έλεγχο.
-
bne:
μοιάζει με την beq που ήδη έχετε,
αλλά η συνθήκη διακλάδωσης είναι αντεστραμένη.
-
jr, jal:
Οι εντολές αυτές μοιάζουν με την j (jump) που ήδη έχετε,
αλλά χρειάζονται νέοι δρόμοι στο datapath
γιά να μπορεί να περάσει ο καταχωρητής regA μέχρι τον PC (jr),
ή ο (ήδη αυξημένος κατά 4) PC
να μπορεί να γραφτεί στο αρχείο καταχωρητών (jal).
Ασκηση 8.2: Προσθήκη Εξαιρέσεων
Προσθέστε στο datapath και στον έλεγχο
όσα χρειάζονται γιά να εκλτελεί ο επεξεργαστής σας
εξαιρέσεις (exceptions).
Η ιδέα είναι η ίδια με ό,τι περιγράφει το βιβλίο
στην παράγραφο 5.6 (σελίδες 410-416),
αλλά εμείς θα έχουμε διαφορετικές αιτίες εξαιρέσεων,
και μία μόνο πρόσθετη κατάσταση ελέγχου, την exception_st,
γιά να τις υλοποιήσουμε.
Οπως και στο βιβλίο, πάντως, θα προσθέσετε στο datapath
δύο νέους (ακμοπυροδότητους) καταχωρητές:
epc (Exception PC), των 32 bits,
γιά να κρατά τη διεύθυνση της "κακιάς" εντολής, και
cause (αιτία), επίσης των 32 bits,
γιά να κρατά έναν κώδικα που υποδεικνύει την αιτία της εξαίρεσης.
Οι αιτίες και οι αντίστοιχες δράσεις θα είναι:
-
Παράνομη Εντολή (Illegal Instruction):
Στη διάρκεια του 2ου κύκλου κάθε εντολής,
δηλαδή κατά την κατάσταση i_decode,
εάν ο έλεγχος διαπιστώσει ότι ο συνδυασμός op-funct
δεν αντιστοιχεί σε καμία από τις εντολές
που ο επεξεργαστής μας ξέρει να εκτελεί
(αυτές των ασκήσεων 7 και 8.1),
θέτει σε 1 το bit [1] του καταχωρητή cause,
και μεταβαίνει, σαν επόμενη κατάσταση, στην κατάσταση exception_st.
-
Παραβίαση Ευθυγράμμισης (Alignment Violation):
Στη μνήμη του MIPS, όλες οι λέξεις (32 bits)
πρέπει να έχουν διεύθυνση που να είναι ακέραιο πολλαπλάσιο του 4,
δηλ. τα 2 LS bits να είναι μηδέν (περιορισμός ευθυγράμμισης).
Το δικό μας υποσύνολο του MIPS
προσπελαύνει πάντα λέξεις (32 bits) όποτε προσπελαύνει τη μνήμη,
και αυτό το κάνει σε 3 περιπτώσεις:
ανάγνωση εντολής (i_fetch),
ανάγνωση δεδομένων (4ος κύκλος της lw), ή
εγγραφή δεδομένων (4ος κύκλος της sw).
Κατά τη διάρκεια αυτών των τριών καταστάσεων (κύκλων),
το κύκλωμα ελέγχου παρακολουθεί τη διεύθυνση ma που δίδεται στη μνήμη:
εάν τα 2 LS bits αυτής της διεύθυνσης δεν είναι 00,
τότε, στο τέλος του κύκλου,
φορτώνει στα bits [3:2] του καταχωρητή cause τον κώδικα:
- 01 αν κάνουμε ανάγνωση εντολής (i_fetch), ή
- 11 αν κάνουμε ανάγνωση δεδομένων (4ος κύκλος της lw), ή
- 10 αν κάνουμε εγγραφή δεδομένων (4ος κύκλος της sw),
και μεταβαίνει, σαν επόμενη κατάσταση, στην κατάσταση exception_st.
Παρατηρείστε ότι η "κακιά" προσπέλαση μνήμης έχει ήδη γίνει,
αλλά θεωρούμε ότι η μνήμη έχει αρκετή δική της προστασία
ώστε ή να αρνηθεί να εκτελέσει την παράνομη προσπέλαση
ή να αγνοήσει τα 2 μη μηδενικά LS bits της διεύθυνσης.
-
Σφάλμα Σελίδας Μνήμης (Page Fault):
Σ' έναν πραγματικό υπολογιστή MIPS με εικονική μνήμη (virtual memory),
όπως θα μάθουμε αργότερα,
ορισμένες διευθύνσεις μνήμης αντιστοιχούν σε "σελίδες" (pages)
που βρίσκονται στην κύρια μνήμη, ενώ άλλες όχι.
Κάθε προσπέλαση σε απούσα σελίδα μνήμης προκαλέι μιάν εξαίρεση
γνωστή σαν "σφάλμα σελίδας" (page fault).
Στον δικό μας επεξεργαστή των ασκήσεων 6 και 7,
η μνήμη έχει μόνο 1024 λέξεις, στις χαμηλές διευθύνσεις,
άρα γιά μας σφάλμα σελίδας θα είναι κάθε προσπέλαση
σε διεύθυνση μνήμης μεγαλύτερη ή ίση του 4096
(1024 λέξεις = 4096 bytes).
Επιπλέον, ο επεξεργαστής μας θα θεωρεί σφάλμα σελίδας
κάθε προσπέλαση στη διεύθυνση μνήμης 0,
ούτως ώστε να μην περνάν απαρατήρητες
οι παράνομες προσπελάσεις μνήμης μέσω NULL pointers
(άρα, διεύθυνση εκκίνησης του PC δεν μπορεί να είναι η 0).
Τα σφάλματα σελίδας μπορούν να εμφανιστούν
στις ίδιες καταστάσεις (κύκλους) όπως και οι παραβιάσεις ευθυγράμμισης
που είδαμε παραπάνω,
και μάλιστα μπορεί να εμφανιστούν και ταυτόχρονα με εκείνες.
Ετσι, η ανίχνευση και η αντίδραση θα είναι κοινή
γιά αυτούς τους δύο τύπους εξαιρέσεων.
Τα σφάλματα σελίδων, όταν συμβαίνουν,
θα φορτώνουν στα bits [5:4] του καταχωρητή cause τον κώδικα
01, ή 11, ή 10,
κατ' αντιστοιχία με τις παραβιάσεις ευθυγράμμισης
(i_fetch, lw, sw, αντίστοιχα),
και θα μεταβαίνουν, σαν επόμενη κατάσταση, στην κατάσταση exception_st.
Παρατηρείστε ότι η "κακιά" προσπέλαση μνήμης έχει ήδη γίνει,
αλλά θεωρούμε ότι η μνήμη έχει αρκετή δική της προστασία
ώστε να αρνηθεί να εκτελέσει την προσπέλαση
όταν η διεύθυνση αναφέρεται σε απούσα λέξη.
Τον καταχωρητή cause μπορείτε, αν προτιμάτε, να τον "συνθέσετε"
από 26 (hardwired) μηδενικά στα 26 MS bits,
έναν καταχωρητή των 2 bits "cause_pagefault" στα 2 επόμενα bits,
έναν καταχωρητή των 2 bits "cause_alignment" στα 2 επόμενα bits,
έναν καταχωρητή του 1 bit "cause_illegalOp" στο 1 επόμενο bit,
και 1 (hardwired) μηδενικό στο 1 LS bit.
Καθένας από τους 3 μικρούς καταχωρητές έχει το δικό του load enable,
το οποίο ανάβει μόνο όταν εμφανιστεί η αντίστοιχη αιτία εξαίρεσης.
Η είσοδος δεδομένων των καταχωρητών cause_alignment και cause_pagefault
είναι κοινή και αποτελεί απλώς συνάρτηση της παρούσας κατάστασης.
Στην κατάσταση exception_st πρέπει
πρώτον να αποθηκεύσουμε τη διεύθυνση της "κακιάς" εντολής
στον καταχωρητή epc,
και δεύτερον να φορτώσουμε στον pc
τη διεύθυνση όπου ξεκινά ο interrupt handler.
Η διεύθυνση της "κακιάς" εντολής είναι το περιεχόμενο του pc
μείον 4 (αφού ο αρχικός pc είχε ήδη αυξηθεί κατά 4).
Την αφαίρεση αυτή, "μείον 4", θα την κάνει η ALU
στη διάρκεια της κατάστασης exception_st
(προσέξτε όμως ότι στο σχήμα 5.48 (σελ. 414) του βιβλίου
ο epc κακώς παίρνει είσοδο δεδομένων από τον ALUout
--έπρεπε να παίρνει από το ALUresult,
προκειμένου η εγγραφή σε αυτόν
να γίνεται στο τελος του κύκλου exception_st).
Οσο γιά τη διεύθυνση όπου ξεκινά ο interrupt handler,
στον μεν κανονικό MIPS αυτή είναι η 32'h80000080,
στην δε δική μας περίπτωση θα την κάνουμε να είναι η 32'd2048,
προκειμένου αυτή να πέφτει μέσα στην υλοποιημένη μνήμη (στη μέση της).
Ασκηση 8.3: Πλήρες Debugging
Ελέγξτε εξονυχιστικά τον επεξεργαστή που σχεδιάσατε,
και διορθώστε όλα τα λάθη που βρίσκετε,
μέχρι ότου αυτός εκτελεί επιτυχώς τα μεγάλα προγράμματα
που θα βρείτε στην περιοχή "~hy225/verilog/test/test8/".
Παραδώστε, όπως και στις προηγούμενες ασκήσεις,
τον αλλαγμένο κώδικά σας "datapath8.v", "control8.v",
και το test bench "test8.v", όπως τελικά τα διαμορφώσατε,
και ένα χαρακτηριστικό στιγμιότυπο από το Signalscan της άσκησης 8.3
με ένα από τα πλέον πολύπλοκα tests (σε μορφή jpeg ή gif),
πακεταρισμένα στο αρχείο "ask8.tar.gz",
μέσω:
tar -cvf ask8.tar datapath8.v control8.v test8.v signals8.gif
gzip ask8.tar
~hy225/bin/submit 8
Προαιρετική Ασκηση 8.4: Βελτιστοποίηση Εντολών Αλματος
Οσοι από σας ενδιαφέρεστε ιδιαίτερα γιά το hardware και έχετε χρόνο,
αλλάξτε το κύκλωμα ελέγχου,
και πιθανόν και το datapath,
προκειμένου οι εντολές άλματος (j, jr, jal)
να εκτελούνται σε δύο (2) μόνο κύκλους ρολογιού
αντί των τριών (3), τώρα, κύκλων ρολογιού.
Προσέξτε οι αλλάγές που κάνετε να μην σας επιμηκύνουν
τη διάρκεια του κύκλου ρολογιού
(τουλάχιστο όχι πάνω από περίπου 1%),
διότι τότε δεν θα συμφέρουν,
δεδομένου ότι οι εντολές που βελτιστοποιείτε
αποτελούν μόνο περίπου το 4% των εκτελουμένων εντολών
των συνηθισμένων προγραμμάτων.