Mips Pipelined Model
Uppgifen är följande:
For the original program, assume the program has reached the loop: label (PC register = 0x00000024) for the first time.
Fill out the table below for the input and output of each register a...o in the figure.Hints:Even if a synchronizer (aka. register) is not used in the active path each synchronizer/register will have both input and output data. For the output of the instruction memory, you can look at Assignment 2 to find the value stored at each address. Assume all registers to have value 0 on reset (program start).To solve this assignment, think about the pipeline. The IM stage reflects the instruction read at the current PC address, DE stage the previous instruction, the EX stage the second previous instruction and so forth.

.text
.set noreorder
main: la $t1, data
la $t2, res
ori $t0, $zero, 0
loop: lb $t4, 0($t1)
beq $t4, $zero, loop2
addu $t0, $t0, $t4
sw $t0, 0($t2)
addi $t2, $t2, 4
addi $t1, $t1, 1
b loop
loop2: b loop2
.data
data: .word 0x01020304
.word 0x00000000
res: .word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
.word 0x00000000
Address Machine Code Instruction
-------------------------------------------------------
0x00000000 0x3c090000 lui $t1, 0
0x00000004 0x25291000 addiu $t1, $t1, 4096
0x00000008 0x3c0a0000 lui $t2, 0
0x0000000c 0x254a1008 addiu $t2, $t2, 4104
0x00000010 0x34080000 ori $t0, $zero, 0
0x00000014 0x812c0000 lb $t4, 0($t1)
0x00000018 0x11800005 beq $t4, $zero, loop2
0x0000001c 0x010c4021 addu $t0, $t0, $t4
0x00000020 0xad480000 sw $t0, 0($t2)
0x00000024 0x214a0004 addi $t2, $t2, 4
0x00000028 0x21290001 addi $t1, $t1, 1
0x0000002c 0x1000fff9 beq $zero, $zero, loop
0x00000030 0x1000ffff beq $zero, $zero, loop2
Address Data Word
----------------------------
0x00001000 0x01020304
0x00001004 0x00000000
0x00001008 0x00000000
0x0000100c 0x00000000
0x00001010 0x00000000
0x00001014 0x00000000
0x00001018 0x00000000
Min lösning är följande: (a, d och e är givna av uppgiften)
| register | input data | output data |
| a | 0x00000028 | 0x00000024 |
| b | 0x00000028 | 0x00000024 |
| c | 0x214a0004 | 0xad480000 |
| d | - | - |
| e | - | - |
| f | 0x00001008 | 0x00000000 |
| g | 0x00000000 | 0x00000000 |
| h | 0x00000024 | 0x00000020 |
| i | 0x00000000 | 0x00004021 |
| j | 01000b | 01000b |
| k | 0x00000000 | 0x00000000 |
| l | 0x00000000 | 0x00000000 |
| m | 01000b | 00000b |
| n | 0x00000000 | 0x00000001 |
| o | 00000b |
01100b |
Dessa svar stämmer dock inte helt. Jag är ganska säker på att b och h stämmer. Men inte de övriga.
Hej! Jag har räknat på den här och tror att jag har fått ihop det mesta nu. Det viktiga är att hoppen avgörs redan i ID-steget och att all forwarding också sker där, så f och g innehåller redan forwardade värden.
I cykeln vi tittar på ligger addi i IF, sw i ID, addu i EX, beq i MEM och lb i WB.
Att PC går till 0x28 (alltså att beq inte hoppar) beror på att $t4 forwardas från ALU-utgången när beq ligger i ID. Då är lb i EX, så det som forwardas är adressen 0x1000 och inte det laddade värdet. 0x1000 är inte noll, så hoppet tas inte.
Mina svar (input / output):
a: 0x00000028 / 0x00000024 b: 0x00000028 / 0x00000024 c: 0x214a0004 / 0xad480000 f: 0x00001008 / 0x00000000 g: 0x00000001 / 0x00000001 h: 0x00000024 / 0x00000020 j: 01000b / 01000b k: 0x00000001 / 0x00001000 l: 0x00000001 / 0x00000000 m: 01000b / 00000b n: 0x00001000 / 0x00000001 o: 00000b / 01100b
Lite förklaring till de mindre självklara:
- g ut: när addu var i ID låg lb i MEM, så den laddade byten (0x01) forwardades till $t4.
- g in: sw läser $t0, och addu i EX skriver $t0 med 0 + 1 = 1, som forwardas direkt från ALU:n.
- k ut: beq:s operander var 0x1000 och 0, så ALU-resultatet blir 0x1000 vare sig den adderar eller subtraherar.
- n in: beq läser inte minnet, så muxen släpper igenom ALU-resultatet 0x1000.
Det jag inte är helt säker på:
- i: jag har inte riktigt förstått vad i är. Immediate verkar ligga i det omärkta registret efter S/Z, så i är nog något annat.
- j in: jag har antagit att sw väljer rt (01000). Om processorn nollställer dest för instruktioner som inte skriver register blir det 00000.
- Jag har räknat med big-endian, så lb ger 0x01. Är det little-endian blir det 0x04 i stället, och då ändras g, k in, l in och n ut.
Säg gärna till om någon har fått något annat!