2. Εργαστήριο 5 – Υποστήριξη εξαρτήσεων και προώθησης δεδομένων στο
Pipelined Datapath
2
Στο εργαστήριο αυτό έπρεπε να επεκτείνουμε το Pipelined Datapath έτσι ώστε να
υποστηρίζει εκτέλεση εντολών με εξαρτήσεις και προώθηση δεδομένων.
Συγκεκριμένα θα έπρεπε να υλοποιήσουμε ένα κομμάτι το οποίο θα έκανε κάποιους
ελέγχους για να διαπιστώσει εάν υπάρχουν εξαρτήσεις δεδομένων ή δομικές
εξαρτήσεις και εάν υπάρχουν θα έκανε προώθηση δεδομένων από τους Pipeline
καταχωρητές κατευθείαν στην είσοδο της ALU.
Οι καταχωρητές που μας ενδιαφέρουν είναι οι ΕΧ/ΜΕΜ και ΜΕΜ/WB από όπου
προέρχονται τα δεδομένα για προώθηση και ο καταχωρητής ID/EX όπου υπάρχει η
εντολή που ίσως παρουσιάζει κάποιου είδους εξάρτηση με τις εντολές που
βρίσκονται στους δυο επόμενους καταχωρητές. Στον επόμενο πίνακα φαίνονται όλοι
οι έλεγχοι που πραγματοποιούνται στα πεδία εγγραφής και ανάγνωσης καταχωρητών
του Register File καθώς και τι είδους εντολή έχουμε σε κάθε Pipeline καταχωρητή.
Pipeline
καταχωρητής
που
περιέχει την
εντολή
πηγής
Είδος
εντολής
Πηγής
Pipeline
καταχωρητής
που
περιέχει την
εντολή
προορισμού
Είδος
Εντολής
προορισμού
Προορισμός
προωθημένων
δεδομένων
Έλεγχος
που γίνεται
EX/MEM Register-
Register
ID/EX Register-Register
Register-
Immediate,
Load,store,
branch
Πάνω είσοδος
ALU
ΕΧ/ΜΕΜ.IR(rd)==
ID/EX.IR(rs)
EX/MEM Register-
Register
ID/EX Register-Register Κάτω είσοδος
ALU
ΕΧ/ΜΕΜ.IR(rd)==
ID/EX.IR(rt)
MEM/WB Register-
Register
ID/EX Register-Register
Register-
Immediate,
Load,store,
branch
Πάνω είσοδος
ALU
MEM/WB.IR(rd)==
ID/EX.IR(rs)
MEM/WB Register-
Register
ID/EX Register-Register Κάτω είσοδος
ALU
MEM/WB.IR(rd)==
ID/EX.IR(rt)
EX/MEM Register-
Immediate
ID/EX Register-Register
Register-
Immediate,
Load,store,
branch
Πάνω είσοδος
ALU
ΕΧ/ΜΕΜ.IR(rt)==
ID/EX.IR(rs)
EX/MEM Register-
Immediate
ID/EX Register-Register Κάτω είσοδος
ALU
ΕΧ/ΜΕΜ.IR(rt)==
ID/EX.IR(rt)
MEM/WB Register-
Immediate
ID/EX Register-Register
Register-
Immediate,
Load,store,
branch
Πάνω είσοδος
ALU
MEM/WB.IR(rt)==
ID/EX.IR(rs)
MEM/WB Register-
Immediate
ID/EX Register-Register Κάτω είσοδος
ALU
MEM/WB.IR(rt)==
ID/EX.IR(rt)
MEM/WB Load ID/EX Register-Register
Register-
Immediate,
Load,store,
branch
Πάνω είσοδος
ALU
MEM/WB.IR(rt)==
ID/EX.IR(rs)
MEM/WB Load ID/EX Register-Register Κάτω είσοδος
ALU
MEM/WB.IR(rt)==
ID/EX.IR(rt)
3. Εργαστήριο 5 – Υποστήριξη εξαρτήσεων και προώθησης δεδομένων στο
Pipelined Datapath
3
Εκτός από τον κώδικα VHDL που γράψαμε για να κάνει τους παραπάνω ελέγχους
αλλάξαμε τους Pipeline καταχωρητές του Datapath έτσι ώστε να περιέχουν και την
εντολή που εκτελείται σε κάθε στάδιο έτσι ώστε να μπορέσουμε να κάνουμε τους
παραπάνω ελέγχους. Μια άλλη αλλαγή που κάναμε ήταν στο ALUSTAGE όπου
προσθέσαμε δυο επιπλέον πολυπλέκτες οι οποίοι επιλέγουν αν οι δυο είσοδοι της θα
είναι από προώθηση δεδομένων ή αν θα προέρχονται από το DECSTAGE όπως
γινόταν πριν προσθέσουμε την λογική για την προώθηση δεδομένων. Έτσι το
σχηματικό διάγραμμα του ALUSTAGE άλλαξε σε σχέση με αυτό που είχαμε πριν
τις αλλαγές ως εξής:
ALUSTAGE
BranchType
Disp
PC+4
A_PC_Sel
B
A
Immed
B_Imm_Sel
ALUfunc
MemRdEn
MemWrEn
RFWrAddr
RFWrValid
DataSel
BranchControl
nPCDisp
nPCReg
nPCPlusI
nPCSel
ΠροςIFSTAGE
ALUOut
RFOut
MemRdEn
MemWrEn
RFWrAddr
RFWrValid
DataSel
ALU
ALULDEn
ALUReset
ALU_Clk
Από MEM/WB
Από EX/MEM
Από EX/MEM
Από MEM/WB
ΠροςIFSTAGE
4. Εργαστήριο 5 – Υποστήριξη εξαρτήσεων και προώθησης δεδομένων στο
Pipelined Datapath
4
Τα στοιχεία που προσθέσαμε φαίνονται με κόκκινο χρώμα ενώ τα δυο σήματα που
ελέγχουν τους δυο νέους πολυπλέκτες και φαίνονται με μπλέ χρώμα είναι 2-bit το
καθένα και παίρνουν τιμή ανάλογα με το τι θα προκύψει από τον έλεγχο.
Έτσι :
με 00 περνάν τα δεδομένα από το DECSTAGE
με 01 περνάν τα δεδομένα από τον καταχωρητή ΕΧ/ΜΕΜ
και με 10 περνάν τα δεδομένα από τον καταχωρητή MEM/WB
Στη συνέχεια προχωρήσαμε στην προσομοίωση έτσι ώστε να δούμε αν εκτελούνται
σωστά όλες οι εντολές. Από την προσομοίωση αυτή διαπιστώσαμε ότι δεν
εκτελούνται σωστά οι εντολές beqz και bneq .Έτσι ξανακάναμε προσομοίωση
χρησιμοποιώντας το Mif αρχείο που μας είχε δοθεί έχοντας αφαιρέσει όλες τις
Branch εντολές. Έτσι το νέο mif που χρησιμοποιήσαμε ήταν το εξής:
WIDTH = 32;
DEPTH = 1024;
ADDRESS_RADIX = DEC;
DATA_RADIX = BIN;
CONTENT BEGIN
0 : 10000000000000010000000000000010; --addi r1,r0,2 [r1=r0+2=0+2=2]
1 : 10000000001000100000000000000011; --addi r2,r1,3 [r2=r1+3=2+3=5]
2 : 10000000010000110000000000000100; --addi r3,r2,4 [r3=r2+4=5+4=9]
3 : 10000000000001010000000000000000; --addi r5,r0,0 [r5=r0+0=0+0=0]
4 : 10000000000001100000000000000000; --addi r6,r0,0 [r6=r0+0=0+0=0]
5 : 10000000000001110000000000000000; --addi r7,r0,0 [r7=r0+0=0+0=0]
6 : 10000000000100000000000000010000; --addi r16,r0,16 [r16=r0+16=0+16=16]
7 : 10000000000101000000000000010100; --addi r20,r0,20 [r20=r0+20=0+20=20]
8 : 01000100000000000000000000001100; --j COMPARE1 [SignExt((Imm<<2))=48,
COMPARE1=INSTRUCTION 12, TAKEN]
9 : 00000000001000000001000000000100; --and r2,r1,r0 [not executed]
10 : 00000000001000100001100000000110; --or r3,r1,r2 [not executed]
11 : 11000010000111100000000000000000; --lw r30,0(r16) [not executed]
12 : 10000000101001010000000000000001; --COMPARE1: addi r5,r5,1
13 : 10000100001000010000000000000001; --subi r1,r1,1
15 : 01000100000000000000000000010010; --j COMPARE2 [SignExt((Imm<<2))=72,
COMPARE2=INSTRUCTION 18, TAKEN, r5=2,r1=0]
16 : 10010000001000100000000000000000; --andi r2,r1,0 [not executed]
17 : 10011000010000110000000000000000; --ori r3,r2,0 [not executed]
18 : 10000000110001100000000000000010; --COMPARE2: addi r6,r6,1
19 : 10000100010000100000000000000001; --subi r2,r2,1
21 : 01000100000000000000000000011000; --j COMPARE3 [SignExt((Imm<<2))=96,
COMPARE3=INSTRUCTION 24, TAKEN, r6=5,r2=0]
22 : 10100101000001110000000001100100; --slti r7,r8,100 [not executed]
23 : 00000011000000000000000000100000; --jr r24 [not executed]
24 : 10000000111001110000000000000001; --COMPARE3: addi r7,r7,1
25 : 10000100011000110000000000000001; --subi r3,r3,1
27 : 01000100000000000000000000011101; --j STORE_VALUES [SignExt((Imm<<2))=116,
STORE_VALUES=INSTRUCTION 29, TAKEN, r7=9,r3=0]
28 : 00000000011001000011100000001001; --slt r7,r3,r4 [not executed]
29 : 11100000000001010000000000000000; --STORE_VALUES: sw r5,0(r0) [M[0]=r5=2]
30 : 11100000000001100000000000000100; --sw r6,4(r0) [M[1]=r6=5]
31 : 11100000000001110000000000001000; --sw r7,8(r0) [M[2]=r7=9]
32 : 01000100000000000000000000100011; --j COUNTER [SignExt((Imm<<2))=140,
COUNTER=INSTRUCTION 35, TAKEN]
33 : 10101000000100000000000110010000; --lui r16,400 [not executed]
34 : 00000000110001110010100000000110; --or r5,r6,r7 [not executed]
35 : 10000010100101000000000000000001; --COUNTER: addi r20,r20,1
5. Εργαστήριο 5 – Υποστήριξη εξαρτήσεων και προώθησης δεδομένων στο
Pipelined Datapath
5
36 : 01000100000000000000000000100011; --j COUNTER [SignExt((Imm<<2))=140,
COUNTER=INSTRUCTION 35, TAKEN]
END;
Έτσι εκτελώντας τις παραπάνω εντολές πήραμε τις εξής κυματομορφές:
Από 0-4 ns
6. Εργαστήριο 5 – Υποστήριξη εξαρτήσεων και προώθησης δεδομένων στο
Pipelined Datapath
6
Από 3.5-7 ns
Από 6.5-10 ns
7. Εργαστήριο 5 – Υποστήριξη εξαρτήσεων και προώθησης δεδομένων στο
Pipelined Datapath
7
Από 9.5-13 ns
Από τις παραπάνω κυματομορφές παρατηρούμε ότι όλες οι εντολές εκτελούνται
σωστά. Βέβαια το πρόγραμμα που υπήρχε στο mif αρχείο δεν εκτελείται σωστά γιατί
όπως είπαμε έχουμε αφαιρέσει τις Branch εντολές.
Συγκεκριμένα εκτελούνται οι εντολές 0 εως 8, από εκεί γίνεται jump στην εντολή
12. Εκεί εκτελούνται οι εντολές 12,13 και 15 αφού έχουμε αφαιρέσει την 14.απο την
15 γίνεται jump στην 18 όπου εκτελούνται οι 18,19 και 21(έχουμε αφαιρέσει την
20).Στη συνέχεια η εκτέλεση πηγαίνει στην 24 και εκτελούνται η 24,25,27(έχουμε
αφαιρέσει την 26).Απο την 27 γίνεται jump στην 29 που εκτελούνται οι 29,30,31,32
από όπου γίνεται jump στην 35 όπου το πρόγραμμα μπαίνει σε ένα loop το οποίο
αυξάνει τον καταχωρητή 20 κατά 1 κάθε φορά.
Παρατηρήσαμε ότι στην εντολή 18 αντί να γραφεί ο καταχωρητής 6 με 1 γράφεται
με την τιμή 2 το οποίο δεν ξέρουμε που οφείλεται καθώς και ότι ο καταχωρητής 20
που παίζει τον ρόλο ενός μετρητή δεν αυξάνεται κάθε 5 κύκλους όπως θα έπρεπε
αλλά κάθε 10 όπως φαίνεται και από τις κυματομορφές. Κάθε τιμή δηλαδή
παρουσιάζεται 2 φορές στον καταχωρητή 20.