Zitat von Martin Elshuber <e9825286@xxxxxxxxxxxxxxxxxxxx>:
es gibt 2 "stalls" die wir unterscheiden müssen
Ich weiß nicht, ob es wirklich zwei Arten gibt. An der "Stallgrenze" muss (immer) ein NOP eingefügt werden. Bei einer BUSY Einheit (Alu oder Datamem) liegt diese Grenze nach der jeweiligen Stage, bei einer Datadependency liegt sie in zwischen ID und EX oder dort wo die Datadependency erkannt wird (so genau hab ich mir das noch nicht angesehen) Ein Stall einer Stage heißt für mich: Das Pipeline-Register dieser Stage wird nicht verändert. D.h. aber dass man nie die "ganze" Pipeline stalled sondern immer nur Teile davon. Ansonsten würde ja keine Veränderung mehr statt finden.
Beispiele: addi r2,r1,7 subi r3,r2,2
Der Stall wird hervorgerufen, durch das was in ID ermittelt wurde und das was in EX (bzw WB) steht (Register Konflikt) D.h. ID und IF werden gestalled, WB übernimmt von EX und EX wird mit NOP gefüllt. Hier ist die "Stallgrenze" zwischen ID und EX.
mul r2,r1,3 add r4,r5,r6
Hier ist die ALU in EX busy und stallt somit jedenfalls IF und ID. Das EX-Register (welches von ID kommt) muss meiner Meinung auch erhalten bleiben (sonst muss bei MUL einer der Operanden nochmal zusätzlich in einem Register landen). In WB muss entsprechend der Dauer von MUL jeden Takt ein NOP eingefügt werden. Hier liegt die "Stallgrenze" zwischen EX und WB. Kann ein Branch auch zu einem stall oder nur zu einem flush führen? Mahlzeit Günther