Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
Notes on this paper
3-hour closed-book exam. Questions 1 and 2 are mandatory; the first five questions answered constitute a complete paper (Q6 is answered here as well, for completeness). Reference texts: Patterson & Hennessy, Computer Organization and Design, 6th ed.; Mano & Ciletti, Digital Design, 6th ed.
Given. (a) MIPS32's fixed 32-register integer and floating-point files, R/I/J formats. (b) 20 instructions (16-bit encoding each), 3 memory-read and 1 memory-write instructions, each access moving 2 bytes. (c) the 32-bit word 0x00126700 sitting at address 0x80120234.
Find. (a)(i) Benefits/challenges of widening the register file; (a)(ii) why keep separate int/FP files; (b) the minimum bytes read from memory over the 20-instruction sequence; (c) whether the given word is plausibly an instruction, data, or either.
Approach. (a) reason from instruction-encoding cost and compiler register pressure; (b) separate instruction-fetch traffic from data traffic and sum only the reads; (c) decode the word's high-order bits against the MIPS R-format field layout.
Part (a)(i) — more registers: benefits and challenges. More architectural registers let the compiler keep more live values on-chip instead of spilling to the stack, which cuts load/store traffic and can shorten the critical path for register-heavy code (loop unrolling, deeply nested expressions, function calls with many live locals). The challenge is encoding cost: MIPS's fixed 32-bit instruction word allocates 5 bits per register specifier (2^5 = 32 registers); doubling the register count to 64 needs 6-bit fields, and a 32-bit R-format instruction with three register operands (rs, rt, rd) already uses 15 of those bits — there isn't room to grow all three fields without either widening the instruction (breaking fixed-width fetch/decode and code density) or shrinking the opcode/funct/shamt space instead. Register files also get slower and more power-hungry as their read/write port count and entry count grow (more read ports for wide issue, larger decoders), and every additional architectural register is another value the OS must save/restore on every context switch. More registers trade lower spill traffic for wider (or renegotiated) instruction encoding and a larger, slower, more power-hungry register file.
Part (a)(ii) — separate integer and floating-point register files. Splitting the two files lets integer and floating-point instructions issue and execute independently—an FP-heavy loop's register traffic never contends with the integer pipeline's, so a superscalar machine can dispatch one integer and one FP instruction in the same cycle without a shared-port hazard. It also lets each file be sized and ported for its own workload (FP code often needs fewer, wider registers with different rounding/exception state) and keeps the two data types physically separate. This is why MIPS defines both a 32-entry GPR file and a 32-entry FPR file rather than one shared 64-entry file. Separate files remove port contention between integer and FP execution and let each file's width/porting be tuned to its own data type.
Part (b) — minimum bytes read from memory. Every one of the 20 instructions must be fetched from memory regardless of what it does, at 16 bits (2 bytes) each:
$$\text{fetch bytes}=20\times2=40\ \text{bytes}$$
Only the three memory-read instructions pull additional data from memory (2 bytes each); the memory-write instruction sends data to memory, it does not read data from it, so it adds nothing to this count:
$$\text{data-read bytes}=3\times2=6\ \text{bytes}$$
$$\boxed{\text{minimum bytes read}=40+6=46\ \text{bytes}}$$
Part (c) — instruction, data, or either? Interpreting 0x00126700 as an R-format MIPS instruction (op[31:26] rs[25:21] rt[20:16] rd[15:11] shamt[10:6] funct[5:0]) gives op = 0 (the SPECIAL/R-format opcode), rs = 0, rt = 18 (\$18), rd = 12 (\$12), shamt = 28, funct = 0. Funct 0 is sll (shift-left-logical), and sll requires rs = 0, which it is here — so this bit pattern decodes into the perfectly valid, well-formed instruction sll $12, $18, 28 (\$12 = \$18 << 28). At the same time, any 32-bit pattern is equally valid as a data value (e.g., the unsigned integer 1,206,016, or a packed record, or part of a string). Because MIPS is a von Neumann architecture—instructions and data share one physical memory and one encoding space—there is nothing in the bits themselves that marks intent; only the access path disambiguates it: if the processor fetched this word via the program counter (instruction fetch), it is being used as an instruction; if a load/store instruction reads it as an operand, it is data. Either — the encoding is a valid instruction (sll \$12,\$18,28) AND a valid data value; only how the processor reaches this address (PC-fetch vs. load/store) tells you which.
Final results — Question 1
Part
Result
(a)(i)
Fewer spills but wider/renegotiated encoding, larger/slower register file, more context-switch state
(a)(ii)
Removes int/FP port contention; lets each file be sized for its data type
(b)
$\boxed{46}$ bytes (40 fetch + 6 data-read; the write does not count)
(c)
Either — decodes as valid sll \$12,\$18,28 (op=0, rs=0, rt=18, rd=12, shamt=28, funct=0) or as plain data