Intuition The one core idea
A processor only understands numbers that are secretly instructions — a fixed-width pattern of bits where some bits say what to do and some say which data to use . RISC-V leaves a few of those bit-patterns permanently blank so you can invent your own "do-this" code that fires a custom hardware unit, without ever confusing normal software.
Before you can understand custom instructions, you must be able to read a plain instruction bit by bit. This page builds every word and symbol the parent note leans on, starting from "what is a bit" and ending at "why 1024 ops fit in one opcode slot". Nothing here is assumed — if the parent used it, we define it.
Definition Bit pattern / word
A word here is a row of exactly 32 bits sitting side by side, e.g. 0000000 00010 00001 000 00011 0110011 . A RISC-V instruction is one such 32-bit word — there is no separate "instruction thing", just a number the CPU agrees to interpret as a command.
Look at the figure: 32 little boxes in a row, numbered from the right . The rightmost box is bit 0 , the leftmost is bit 31 . This numbering direction matters because the CPU decides "what kind of instruction is this?" by reading the boxes on the right first.
inst[6:0]
The square-bracket slice inst[6:0] means: "take the word called inst and keep only bits 6 , 5 , 4 , 3 , 2 , 1 , 0 " — the rightmost 7 boxes . Written high-number first, low-number last. So inst[6:0] is a 7-bit sub-pattern.
Why the topic needs it: those 7 bits are the opcode — the very first thing the hardware reads to know what family an instruction belongs to. The whole idea of "custom opcode space" is a statement about the possible values of inst[6:0].
The opcode is the pattern in inst[6:0]. It answers one question: what category of operation is this word? — an add? a load? a branch? a custom thing?
Since 7 bits can take 2 7 = 128 different patterns, there are at most 128 possible opcode families.
Intuition Why 7 bits, and why it's the anchor of the whole topic
Every RISC-V instruction, no matter its shape, uses the same rightmost 7 bits as its opcode. This is the contract : normal software only ever emits certain opcode values, so if RISC-V promises to never use four specific patterns for standard instructions, those four are yours forever. That promise is literally a promise about four numbers you can put in inst[6:0].
A register is a tiny, ultra-fast storage box inside the CPU that holds one word. RISC-V has 32 of them, named x 0 through x 31 . Reaching a register takes essentially zero extra time compared to reaching main memory (which is far away and slow).
To name one of 32 registers you need a number from 0 to 31 , and 2 5 = 32 , so 5 bits name exactly one register.
rs1, rs2, rd
These are 5-bit fields inside an instruction:
rs1 = "r egister s ource 1 " — the first input.
rs2 = "r egister s ource 2 " — the second input.
rd = "r egister d estination" — where the answer goes.
They choose which data , not which operation . Remember that distinction — it is the seed of the whole "encoding budget" calculation.
The figure shows the register file as a stack of 32 boxes with two arrows leaving it (the two read ports , feeding rs1 and rs2) and one arrow entering it (the one write port , driven by rd). This exact shape — two read, one write — is why the parent note keeps saying "the hardware barely changes": your custom instruction just plugs into ports that already exist.
Once the opcode says "this is an arithmetic-shaped instruction", the CPU still needs to know which one: add? subtract? multiply? These extra selector bits are the funct fields.
funct3 and funct7
funct3 = a 3-bit sub-selector.
funct7 = a 7-bit sub-selector.
Together they refine the opcode: opcode picks the room , funct3/funct7 pick the exact operation inside that room . They select operation , never data.
Intuition Why split the selector into two pieces (3 + 7)?
Historically the 3-bit funct3 sits in a handy spot and covers common cases cheaply; the wider funct7 gives extra room for rarer variants (like distinguishing add from subtract that otherwise look identical). For our purposes the split doesn't matter — what matters is the total free selector bits, which we'll add up next.
Definition R-type instruction format
The R-type ("register type") is the instruction shape that reads two registers and writes one. Its 32 bits are carved up as:
7 funct7 5 rs2 5 rs1 3 funct3 5 rd 7 opcode
Add them: 7 + 5 + 5 + 3 + 5 + 7 = 32 . Every bit accounted for.
The figure colours each field: the two data fields (rs2, rs1, rd) in one hue, the two operation-selector fields (funct7, funct3) in another, and the opcode in a third. Custom instructions borrow this exact skeleton so the CPU's existing decode wiring can be reused — see R-type instruction format .
Common mistake "The register fields help choose which operation runs."
Why it feels right: they're right there in the instruction, so surely they contribute.
The fix: rs1/rs2/rd only pick which boxes hold the inputs and output. Two mac x1,x2,x3 and mac x4,x5,x6 are the same operation on different data. Only opcode + funct3 + funct7 decide what the operation is .
Now every symbol in the parent's key derivation is defined, so we can actually count.
Intuition The counting principle (why we use powers of two)
If a field is k bits wide, it can hold 2 k distinct patterns — because each bit doubles the possibilities: 1 bit → 2, 2 bits → 4, 3 bits → 8, and so on. To count combinations of two independent fields you multiply their counts.
Worked example Sanity check by hand
2 3 = 8 (funct3 patterns) and 2 7 = 128 (funct7 patterns). 8 × 128 = 1024 . Four slots: 1024 × 4 = 4096 . That's the entire custom R-type budget, and every number in it traces back to a field width you can now read off the R-type row.
Definition Clock cycle & latency
A clock cycle is the CPU's smallest heartbeat of time. Latency = how many cycles you wait between asking for a result and getting it. Fewer cycles = faster.
Definition Memory-mapped I/O (MMIO)
MMIO is a way to talk to hardware outside the CPU by reading/writing special memory addresses. It works, but each round-trip crosses a slow bus — hundreds of cycles . See Memory-mapped I/O .
Intuition Why a custom instruction wins for small, frequent ops
A custom instruction lives inside the pipeline: inputs arrive straight from registers (near-zero cost), the result lands straight back in a register — a few cycles . MMIO would spend hundreds of cycles just delivering the operands. This "how close is the unit?" question is exactly the tightly-coupled vs loosely-coupled choice the parent describes — and it's the reason custom instructions exist at all. Compare with Hardware accelerators vs general-purpose CPUs .
Speedup = (time before) ÷ (time after). A speedup of 5 × means the new version finishes in one-fifth the time.
Intuition Why Amdahl's Law limits every accelerator
If you only speed up the part of a program that took, say, 80% of the time, the other 20% still runs at old speed — so total gain is capped no matter how fast the accelerator is. That's why the parent insists you profile first and only harden the hot kernel. Full treatment in Amdahl's Law .
Read top to bottom: bits build a word; the word's rightmost 7 bits are the opcode; the opcode plus the funct fields plus the register fields build the R-type row; counting the funct bits gives the 1024 budget; the reserved opcodes plus that budget give you a custom extension , and the latency/coupling and speedup ideas tell you when it's worth building .
How many bits is one RISC-V opcode, and where does it sit? 7 bits, in inst[6:0] — the rightmost 7 boxes of the 32-bit word.
Why do 5 bits name a register? Because there are 32 registers and 2 5 = 32 .
What do rs1, rs2, rd select — operation or data? Data (which registers hold inputs/output), never the operation.
What do funct3 and funct7 select? The specific operation (flavour) within an opcode family.
How many bits does an R-type instruction total, field by field? 7 + 5 + 5 + 3 + 5 + 7 = 32 .
Why does a k -bit field hold 2 k patterns? Each added bit doubles the possibilities.
Derive operations per custom slot. 2 3 × 2 7 = 8 × 128 = 1024 .
Why is a custom instruction faster than MMIO for small ops? Operands come from registers in a few cycles instead of a hundreds-of-cycles bus round-trip.
What does Amdahl's Law warn about accelerators? The un-accelerated part caps the total speedup, so only harden the hot kernel.