5.1.2 · D4Instruction Set Architecture (ISA)

Exercises — Instruction formats and encoding

2,580 words12 min readBack to topic

Before we start, one picture fixes the vocabulary we lean on the whole page.

Figure — Instruction formats and encoding

We also reuse the field-width law from the parent:


Level 1 — Recognition

Recall Solution L1.1

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 registers (Registers and the Register File), and . Five bits give exactly 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.


Level 2 — Application

Recall Solution L2.1

Check the neighbours: (too few), (fits). So bits, leaving spare patterns for future instructions. Why ceil: ; 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): Assemble in order funct7 rs2 rs1 funct3 rd opcode: 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 -bit two's-complement number (Two's Complement and Sign Extension) spans With : up to . 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.


Level 3 — Analysis

Recall Solution L3.1

Those upper 12 bits become the 12-bit immediate. I-type layout: Why 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. Why 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 bits remain for everything else. A single R-type needs 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.


Level 4 — Synthesis

Recall Solution L4.1
  • Opcode: . Since , opcode = 9 bits.
  • Each register: bits. Three of them = 18 bits.
  • Total used: bits.
  • Word is 32 → spare = 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 + rd + rs1 bits. Immediate gets the rest: bits. As a two's-complement value (Two's Complement and Sign Extension), 11 bits span Why signed: instructions like "add " must work, so the top bit is a sign bit and decode sign-extends the 11 bits to 32 before the ALU touches them.


Level 5 — Mastery

Recall Solution L5.1

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: So the value is . Decode sign-extends it (copies the top 1 leftward) to a 32-bit so the ALU adds a true , 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: Read as binary: . The set bits are at positions 6 and 2 (counting from 0), so value . 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 and must sum to the word width; immediates may be signed, sign-extended, scaled, or split — the raw bits are not always the value.

Active recall

Which field does decode read first, and why
The opcode — it is pinned to a fixed position so decode can pick the format before locating any other field.
Bits needed to index things
, because bits give patterns and you need .
Why does S-type split its immediate
So rs1 and rs2 keep their fixed positions; the immediate goes into the two leftover holes.
Range of a 12-bit signed immediate
to .