The lowest 7 bits hold the opcode.
Why there: the decoder must know what kind of instruction this is before it knows where the other fields live. By pinning the opcode to a fixed spot (the bottom 7 bits in every format), the fetch/decode hardware can read it without first parsing anything else. Think of it as the label on the outside of the box.
Recall Solution L1.2
Three register fields: rd, rs1, rs2. Each is 5 bits wide.
Why 5: RISC-V has 32 registers (Registers and the Register File), and b=⌈log232⌉=5. Five bits give exactly 25=32 patterns — a perfect fit, no waste.
Recall Solution L1.3
Fixed-length. Every instruction is the same width (32 bits = 4 bytes), so the opcode never moves. This is what makes decoding cheap and pipelineable. Variable-length (like x86) would force the CPU to first discover where each instruction ends.
b=⌈log2200⌉.
Check the neighbours: 27=128<200 (too few), 28=256≥200 (fits). So b=8 bits, leaving 256−200=56 spare patterns for future instructions.
Why ceil:log2200≈7.64; you cannot buy a fraction of a bit, so round up.
Recall Solution L2.2
Convert the registers to 5-bit binary (each field is 5 wide):
rd=8=01000,rs1=9=01001,rs2=10=01010.
Assemble in order funct7 rs2 rs1 funct3 rd opcode:
funct70100000rs201010rs101001funct3000rd01000opcode0110011
Grouped as one 32-bit string: 01000000101001001000010000110011.
Why this order: decode reads the opcode from the lowest bits and works leftward, so fields must sit exactly where decode expects them.
Recall Solution L2.3
A b-bit two's-complement number (Two's Complement and Sign Extension) spans
−2b−1to2b−1−1.
With b=12: −211=−2048 up to 211−1=+2047.
Why one extra negative: the pattern 1000...0 is the most negative value and has no positive twin, so the negative side reaches one further.
Those upper 12 bits become the 12-bit immediate. I-type layout:
12imm[11:0]5rs13funct35rd7opcodeWhy exactly 12: the freed funct7(7) + rs2(5) = 12 contiguous bits sit at the top, so the immediate is one clean block — easy to sign-extend to 32 bits.
Notice rs1, funct3, rd, opcode stay in the same positions as R-type — that shared layout is why register-read wiring is identical across formats.
Recall Solution L3.2
A store reads two registers (rs1 = base address, rs2 = data to store), so both register fields must stay in their usual spots. That leaves only the holes — the old rd slot (5 bits) and the old funct7 slot (7 bits) — for the immediate.
7imm[11:5]5rs25rs13funct35imm[4:0]7opcodeWhy split, not shrink: we cannot drop rs2, so the 12-bit immediate is chopped into a 7-bit and a 5-bit piece and stuffed into the two leftover holes. The hardware benefit: ==rs1 and rs2 never move==, so register-read logic is one fixed circuit for R, I, S, and B formats. Only the immediate-reassembly wiring differs.
Recall Solution L3.3
With a 16-bit opcode, only 32−16=16 bits remain for everything else. A single R-type needs 5+5+5=15 bits just for three registers, plus function selectors — it won't fit, and an I-type would have almost no room for a useful immediate.
The real lesson: the 32-bit word is a fixed budget. Every bit handed to the opcode is stolen from operands. Real ISAs keep the opcode small (7 bits) and expand operations sideways with funct3/funct7. This is a core RISC vs CISC design pressure.
Opcode: ⌈log2500⌉. Since 28=256<500≤512=29, opcode = 9 bits.
Each register: ⌈log264⌉=6 bits. Three of them = 18 bits.
Total used: 9+18=27 bits.
Word is 32 → spare = 32−27=5 bits (usable for a funct field, a flag, or future growth).
Why it fits: we spent bits only where the requirements demanded them and checked the running sum against the 32-bit budget — exactly the parent's "total width = sum of field widths" rule.
Recall Solution L4.2
Fixed costs: opcode 9 + rd6 + rs16=21 bits.
Immediate gets the rest: 32−21=11 bits.
As a two's-complement value (Two's Complement and Sign Extension), 11 bits span
−210to210−1=−1024to+1023.Why signed: instructions like "add −8" must work, so the top bit is a sign bit and decode sign-extends the 11 bits to 32 before the ALU touches them.
Slice the word using the R-type map funct7 rs2 rs1 funct3 rd opcode:
funct7 = 0000000, funct3 = 000 → operation is add.
rs2 = 00111 = 7 → source 2 is x7.
rs1 = 00101 = 5 → source 1 is x5.
rd = 00001 = 1 → destination is x1.
Assembly: add x1, x5, x7 (RISC-V writes rd, rs1, rs2).
Why this order in text: the assembler prints destination first, then sources — the opposite visual order to the bit layout, which is a classic trip-up.
Recall Solution L5.2
The top bit of the 12-bit field is 1, so this is a negative two's-complement number. To read it, invert and add one:
111111111000invert000000000111=7+18.
So the value is −8. Decode sign-extends it (copies the top 1 leftward) to a 32-bit −8 so the ALU adds a true −8, not a huge positive number.
The instruction is addi rd, rs1, -8.
Recall Solution L5.3
Concatenate the two pieces in the right order — high bits first, low bits second:
imm[11:5]∥imm[4:0]=0000010∥00100=000001000100.
Read as binary: 0000010001002. The set bits are at positions 6 and 2 (counting from 0), so value =26+22=64+4=68.
Top bit is 0 → positive, no sign-extension changes the value.
Why reassemble: the store's effective address is rs1 + 68; the split is purely a storage trick to keep rs1/rs2 fixed — see the S-type map in L3.2.
Recall One-line summary of the whole ladder
Opcode is fixed and read first; other fields are sized by ⌈log2N⌉ and must sum to the word width; immediates may be signed, sign-extended, scaled, or split — the raw bits are not always the value.