5.1.7 · Hardware › Instruction Set Architecture (ISA)
Intuition The big picture
RISC-V ek open instruction set architecture (ISA) hai — hardware aur software ke beech ek contract . Base integer ISA deliberately tiny rakha gaya hai: sirf itni instructions ki ek poora computer chal sake, aur baaki sab kuch optional extensions ke roop mein add hota hai. Isse ek bhaasha ki "grammar" samjho: RV32I tumhe ~40 verbs deta hai, aur tum unhi se har program banate ho.
RV32I = base integer ISA with 32-bit registers.
RV64I = same philosophy, lekin 64-bit registers (wider address space, wider integers).
Intuition Why a minimal base?
Real CPUs bahut alag-alag hote hain (tiny embedded chips vs. giant servers). Ek bloated ISA banane ki jagah, RISC-V ek small mandatory core (I) define karta hai jise sabhi implement karte hain, plus optional letters:
M = multiply/divide, A = atomics, F/D = floating point, C = compressed 16-bit instructions.
Ek chip khud ko e.g. RV64IMAFDC ("RV64G" for the common general set) advertise karta hai.
WHY minimal wins: simple hardware → smaller, faster, easier to verify; compiler hi heavy lifting karta hai. Yahi classic RISC bet hai: do fewer, simpler things, but do them fast .
RV32I/RV64I mein 32 general-purpose registers hote hain jinka naam x0–x31 hai, har ek XLEN bits wide, jahan ==XLEN = 32 for RV32I and 64 for RV64I==. Plus ek program counter pc.
x0 hardwired to zero hai — hamesha 0 read karta hai, writes discard ho jaate hain.
Koi dedicated flags register nahi hai (x86 jaise carry/zero flags nahi hote).
x0 = 0 so clever?
Ek constant-zero register hone se tum kai "pseudo-instructions" free mein bana sakte ho:
mv rd, rs (move) = addi rd, rs, 0
li rd, 0 = addi rd, x0, 0
nop = addi x0, x0, 0
branch-if-zero = branch jo x0 se compare kare.
Ek design decision se dozen special opcodes ki zaroorat khatam ho jaati hai.
Har RV32I instruction exactly 32 bits ki hoti hai (fixed length → trivial fetch/decode). Bits ko fields mein kaata jaata hai. Genius yeh hai ki fields same jagah rehti hain across formats, isliye decoder unhe parallel mein extract kar sakta hai.
Definition The 6 instruction formats
R-type : register–register ops (add, sub, and, sll). Fields: funct7 | rs2 | rs1 | funct3 | rd | opcode.
I-type : register–immediate + loads (addi, lw, jalr). 12-bit immediate.
S-type : stores (sw, sb). 12-bit immediate split taaki rs1/rs2 apni jagah rahe.
B-type : conditional branches (beq, blt). Immediate ek multiple of 2 encode karta hai (halfword-aligned target).
U-type : upper-immediate (lui, auipc). 20-bit immediate → upper bits.
J-type : jumps (jal). 20-bit immediate, multiple of 2.
Intuition Why split the immediate weirdly (S/B/J)?
Register fields rs1, rs2, rd kabhi move nahi karte formats ke beech. Unhe fixed rakhne ke liye, immediate baaki bache bits mein bikhar jaata hai. Decoder thoda cost pay karta hai (ek MUX immediate reassemble karne ke liye) taaki register reads instruction fully decode hone se pehle shuru ho sakein. Speed over prettiness.
addi x5, x6, -1
Goal: x 6 + ( − 1 ) ko x 5 mein daalo.
Format = I-type. opcode = 0010011, funct3 = 000 (ADDI).
rd = 5 (00101), rs1 = 6 (00110).
imm = − 1 = 12-bit 1111 1111 1111.
Assembled [31:20]=imm, [19:15]=rs1, [14:12]=funct3, [11:7]=rd, [6:0]=opcode.
Why this step? Immediate top 12 bits mein rehta hai; hardware 1111... ko sign-extend karta hai → all-ones → x 5 = x 6 − 1 . Alag "subtract-immediate" instruction ki zaroorat nahi (negative imm use karo).
Worked example 2) Load a 32-bit constant
0xDEADBEEF into x10
12-bit immediate 32 bits hold nahi kar sakta, isliye hum ise split karte hain:
lui x10, 0xDEADC # x10 = 0xDEADC000 (upper 20 bits)
addi x10, x10, -273 # 0xEEF = -273 in 12-bit signed, adds low 12 bits
Why 0xDEADC not 0xDEADB? Kyunki addi ka immediate signed hota hai. 0xEEF ka top bit set hai → yeh negative hai (− 273 ). Compensate karne ke liye hum upper part ko 1 se round up karte hain (0xDEADB → 0xDEADC) taaki negative add exactly 0xDEADBEEF par land kare. Yahi li pseudo-instruction automatically karta hai.
Worked example 3) A loop with a branch
loop:
addi x1, x1, -1 # counter--
bne x1, x0, loop # if x1 != 0, go back
Why compare with x0? Koi "compare-to-zero" opcode ki zaroorat nahi — zero register hi constant hai. bne pc + offset compute karta hai jahan offset negative hai (loop peeche hai), sign-extended.
Definition RV64I differences
Registers aur pc 64 bits ke hain (XLEN = 64); addresses 64-bit hain.
Naye word instructions low 32 bits par operate karte hain aur sign-extend karte hain 64 tak: addw, subw, sllw, lwu (load word unsigned), ld/sd (load/store doubleword).
addi abhi bhi 12-bit immediate use karta hai — bas ab 64 bits tak sign-extend hota hai.
*w instructions instead of just using add?
Bahut saara software (aur 32-bit arithmetic) aise results chahta hai jo 32 bits par "wrap" kare. addw exact 32-bit modular arithmetic deta hai (phir sign-extend karta hai) taaki C ka int 64-bit machine par sahi behave kare — manually masks simulate kiye bina.
Common mistake "Registers are 32 in RV32
I because it's 32-bit."
Why it feels right: "32" do baar dikhta hai. The truth: RV32I mein "32" register width (XLEN) hai; registers ki count hamesha 32 hai chahe RV32I ho ya RV64I. Ye dono 32 coincidence hain. Fix: XLEN = data width; register count = 32 regardless.
Common mistake "The J-type immediate is 20 bits, so a jump reaches ±2^19 bytes."
Why it feels right: 20-bit signed number → ± 2 19 . The truth: stored bit 0 implicit hai (0), isliye field 2 se scale hota hai: range ± 2 20 bytes (±1 MiB) hai. Fix: hamesha yaad rakho ki branch/jump offsets 2 bytes ke units mein hote hain.
li x10, 0xEEF just puts 0xEEF in the register."
Why it feels right: yeh ek chhota number lagta hai. The truth: addi ka 12-bit immediate signed hai; 0xEEF (bit 11 set) sign-extend hokar 0xFFFF...FEEF ban jaata hai. Clean positive 0xEEF paane ke liye tumhe sign clear karne ke liye lui+addi pair chahiye. Fix: koi bhi 12-bit value jisme bit 11 set ho, negative hai.
Recall Answer before expanding
Kitne GPRs hain, aur x0 mein kya khaas hai? → 32; x0 hardwired zero hai.
RV32I mein instruction length? → Fixed 32 bits.
S/B immediates split kyun hote hain? → rs1/rs2/rd fields ko fixed positions mein rakhne ke liye taaki fast decode ho sake.
RV32I vs RV64I mein difference? → XLEN (32 vs 64) + word (*w) aur ld/sd instructions.
Poora 32-bit constant kaise load karte hain? → lui (upper 20) + addi (lower 12), signed low ke liye correct karte hue.
Recall Feynman: explain to a 12-year-old
Ek chef ki imagine karo jiske paas sirf 40 basic moves hain (chop, stir, pour…). Yahi RISC-V base hai. Koi bhi dish (program) bas in moves ki ek lambi list hai. 32 numbered bowls (registers) hain ingredients rakhne ke liye, aur bowl #0 magic hai: yeh hamesha khaali (zero) rehta hai — "nothing" ke liye super handy. Har recipe card same size ki hai isliye chef unhe bahut fast padhta hai. Agar tumhe bada kitchen chahiye, tum extra move-packs add karo (multiply, floating point) — lekin 40 basics kabhi nahi badalte. RV64 bas bade bowls use karta hai jo bade numbers hold karte hain.
Mnemonic Formats & the zero trick
"Really Interesting Students Being Unusually Joyful" → R, I, S, B, U, J (the 6 formats).
Aur: "x0 = a free NOP, MV, and LI" — zero register apni jagah justify karta hai yaad rakho.
How many general-purpose registers does RV32I/RV64I have? 32 (x0–x31), har ek XLEN bits wide.
What is special about register x0? Hardwired to 0; reads 0 deta hai, writes discard ho jaate hain.
What does XLEN mean and what is it for RV32I vs RV64I? Register/data width; RV32I ke liye 32, RV64I ke liye 64.
Instruction length in the RV32I base ISA? Fixed 32 bits (sabhi instructions).
Name the six RV32I instruction formats. R, I, S, B, U, J.
Why are the S/B immediates split across scattered bits? Taaki rs1/rs2/rd fields fixed positions mein rahe aur decode/register-read jaldi shuru ho sake.
What is the range of a 12-bit signed I-immediate? [-2048, 2047].
How do you load a 32-bit constant into a register? lui (upper 20 bits) + addi (lower 12), upper part ko round up karo agar low 12 bits negative ho.
How is a branch offset formed? target = pc + sext(imm), jahan imm[0]=0 (multiple of 2 bytes).
What extensions make "RV64G"? I + M + A + F + D (+C conventionally) — general-purpose set.
What new instructions does RV64I add over RV32I? Word ops (addw, subw, sllw, lwu) aur 64-bit ke liye ld/sd; results 64 bits tak sign-extended hote hain.
How is nop encoded in RISC-V? addi x0, x0, 0.
Does RISC-V have a flags/condition-code register? Nahi; branches directly registers compare karte hain.
Why sign-extend the immediate? Taaki negative immediates (e.g. addi with -1) all-ones produce kare aur naturally kaam kare.
Instruction Set Architecture (ISA) — parent concept: hardware/software contract.
RISC vs CISC — woh design philosophy jo RISC-V embody karta hai.
Two's Complement — isliye immediates sign-extend hote hain.
Pipelining — fixed-length + fixed field positions decode/pipeline ko simpler banate hain.
Addressing Modes — RISC-V memory ke liye sirf base+offset use karta hai.
Assembler & Pseudo-instructions — li, mv, nop, j base ops mein expand hote hain.
Optional extensions M A F D C
Fixed 32-bit instructions