5.1.7 · D4 · HinglishInstruction Set Architecture (ISA)

ExercisesRISC-V base ISA (RV32I - RV64I)

2,899 words13 min read↑ Read in English

5.1.7 · D4 · Hardware › Instruction Set Architecture (ISA) › RISC-V base ISA (RV32I - RV64I)

Shuru karne se pehle, ek shared vocabulary reminder — earned, not assumed:

Neeche diya figure pehle bullet ko picture mein convert karta hai — ise abhi study karo, kyunki is page ke har exercise ka ultimate connection isi ek move se hai.

Figure — RISC-V base ISA (RV32I - RV64I)

Level 1 — Recognition

L1.1

RV32I mein kitne general-purpose registers (GPRs) hain, aur RV64I mein kitne hain?

Recall Solution

Dono mein exactly 32 GPRs hain jinka naam x0x31 hai. "32" jo naam RV32I mein hai woh register width (XLEN = 32 bits) hai, count nahin. RV64I mein bhi 32 registers hain; woh bas 64 bits wide hain. Answer: 32 aur 32.

L1.2

Kaunsa register hardwired to zero hai, aur jab tum usmein write karte ho toh kya hota hai?

Recall Solution

x0. Reads hamesha return karte hain; writes silently discard (throw away) ho jaate hain. Isliye nop = addi x0, x0, 0: yeh kuch compute karta hai, phir result trash-bin register mein dump karta hai.

L1.3

Ek single RV32I instruction kitne bits long hoti hai, aur fixed length kyun help karta hai?

Recall Solution

32 bits (4 bytes), fixed. Fixed length ka matlab hai CPU ko hamesha pata hota hai agla instruction kahan shuru hoga bina current wala decode kiye — fetch aur decode trivial aur fast ho jaate hain. Yeh ek core RISC design choice hai.


Level 2 — Application

L2.1

Ek I-type immediate ek 12-bit signed field hai. Iska numeric range kya hai?

Recall Solution

Ek 12-bit signed (two's-complement) number: top bit sign hai, baaki 11 bits magnitude carry karte hain.

  • Sabse negative: .
  • Sabse positive: . Neeche figure mein dekho ki number line kaise wrap karti hai.
Figure — RISC-V base ISA (RV32I - RV64I)

L2.2

12-bit field 1111 1111 1111 ko addi immediate ke roop mein use kiya jaata hai. Kaunsi signed value add hoti hai, aur addi x5, x6, -1 x5 mein kya chodta hai?

Recall Solution

Top bit hai → negative. Two's complement mein, all-ones = . XLEN bits tak sign-extend karne par yeh phir bhi hai (0xFFFF...FF). Toh addi x5, x6, -1 compute karta hai . Value added: .

L2.3

Ek B-type (branch) immediate 12 bits store karta hai lekin uska bit 0 store nahin hota (hamesha ). pc ke relative branch kितनी byte range tak pahunch sakta hai?

Recall Solution

Stored bits ek signed offset represent karte hain 2 bytes ke units mein. Toh effective offset hai (12-bit signed value) × 2: Roughly KiB. Bit 0 free kyun hai? Base RV32I mein har instruction 4-byte aligned hoti hai, isliye branch target ke low do bits hamesha hote hain — encoding do bits bhi drop kar sakta tha. RISC-V sirf bit 0 drop karta hai (bit 1 nahin) purpose se: agar optional C (compressed) extension present ho, toh instructions kisi bhi 2-byte boundary par ho sakti hain, isliye bit 1 legitimately ho sakta hai. Sirf hamesha-zero bit 0 drop karna reach double kar deta hai aur compressed code ke saath compatible rehta hai.


Level 3 — Analysis

L3.1

addi x5, x6, -1 ko uske 32 bits mein encode karo. Har field do. (opcode = 0010011, funct3 = 000.)

Recall Solution

I-type layout: [31:20]=imm | [19:15]=rs1 | [14:12]=funct3 | [11:7]=rd | [6:0]=opcode.

  • imm = -1 → 12 bits 1111 1111 1111.
  • rs1 = 600110.
  • funct3 = 000.
  • rd = 500101.
  • opcode = 0010011.

Concatenate:

111111111111 00110 000 00101 0010011

32 bits mein group karo aur hex mein padho:

1111 1111 1111 0011 0000 0010 1001 0011
 F    F    F    3    0    2    9    3

Machine code: 0xFFF30293.

L3.2

S-type format (sw jaisi stores ke liye use hota hai) ka yeh field layout hai:

[31:25]=imm[11:5] | [24:20]=rs2 | [19:15]=rs1 | [14:12]=funct3 | [11:7]=imm[4:0] | [6:0]=opcode

Notice karo ki 12-bit immediate do chunks mein split hai — ek high piece imm[11:5] aur ek low piece imm[4:0]. Explain karo ki RISC-V immediate ko aise kyun kaatta hai instead of ise ek clean field mein store karne ke?

Recall Solution

Kyunki register selector fields rs1, rs2, rd saare formats mein fixed bit positions par pinned hain. S-type ko I-type ([31:20]=imm | [19:15]=rs1 | [14:12]=funct3 | [11:7]=rd) se compare karo: dono mein rs1 [19:15] par aur funct3 [14:12] par hota hai. Ek store mein rd nahin hota, isliye woh [11:7] bits (jahan rd hota) immediate ke low 5 bits hold karne ke liye recycle ho jaate hain, aur baaki immediate [31:25] mein upar jaati hai. Decoder register file entries padhna shuru kar sakta hai jis pal woh fixed rs1/rs2 bits dekhta hai — before scattered immediate samjha jaaye. Ek chhota MUX imm[11:5] : imm[4:0] ko reassemble karke full 12-bit value banata hai. Cost (thodi wiring) parallel decode + register read kharidta hai, jo Pipelining ke liye matter karne wali speed win hai.

L3.3

li x10, 0xEEF mein, ek student expect karta hai x10 = 0x00000EEF. Dikhao ki agar yeh single addi x10, x0, 0xEEF hota toh x10 mein actually kya aata, aur explain karo.

Recall Solution

0xEEF binary mein 1110 1110 1111 hai — 12 bits, top bit = 1negative. Signed 12-bit number ke roop mein: unsigned, lekin . 32 bits tak sign-extended: 0xFFFFFEEF. Toh naive addi x10, x0, 0xEEF deta hai 0xFFFFFEEF, nahin 0x00000EEF. Real li pseudo-instruction (dekho Assembler & Pseudo-instructions) yeh detect karta hai aur clean positive value produce karne ke liye lui+addi pair emit karta hai.


Level 4 — Synthesis

Is level se pehle hume ek instruction define karni hai jise parent note ne mention kiya tha:

L4.1

0xDEADBEEF ko x10 mein load karne ke liye two-instruction sequence likho, aur arithmetic dikhao ki yeh exact hai.

Recall Solution

0xDEADBEEF ko upper 20 bits aur lower 12 bits mein split karo:

  • Lower 12 bits = 0xEEF = 1110 1110 1111, bit 11 set → signed value .
  • Upper 20 bits naively 0xDEADB hote, toh lui x10, 0xDEADB deta 0xDEADB000.

Kyunki lower add negative hai (), yeh subtract karega, target se neeche land karega. Compensate karne ke liye, upper part 1 se upar round karo: 0xDEADB0xDEADC.

lui   x10, 0xDEADC     # x10 = 0xDEADC000
addi  x10, x10, -273   # + (-273)

Arithmetic check karo clean hex mein (messy decimals ki zaroorat nahin):

  • Note karo , aur 0xEEF = 0x1000 - 0x111.
  • lui deta hai 0xDEADC000.
  • add karne par: 0xDEADC000 - 0x111 = 0xDEADBEEF.

Exactly 0xDEADBEEF par land karte hain. ✓ (Upper field mein +1 precisely woh "borrow" cancel karta hai jo negative low add se hoti hai.)

L4.2

Sirf base RV32I instructions aur zero register use karke ek countdown loop banao jo body 5 baar run kare. Assume karo x1 = 5 entry par.

Recall Solution
loop:
  addi x1, x1, -1     # counter--
  # ... loop body ...
  bne  x1, x0, loop   # agar x1 != 0, branch back

x0 se compare kyun? RV32I mein compare-to-zero opcode nahin hai — lekin zaroorat bhi nahin, kyunki x0 hai hi constant zero. bne x1, x0, loop = "branch agar x1 ≠ 0". Branch offset negative hai (target peeche hai), sign-extended, 2-byte steps mein. x1 = 5 ke saath, trace karo: pehli addi ke baad x1=4, body run hoti hai (run #1), branch liya jaata hai; ... 5vi addi ke baad x1=0, body run hoti hai (run #5), branch nahin liya jaata. Body 5 baar execute hoti hai.


Level 5 — Mastery

L5.1

RV64I par, register x7 mein 0x0000_0000_8000_0000 hai. Tum addw x8, x7, x7 execute karte ho (32-bit add, phir 64 tak sign-extend). x8 mein final 64-bit value kya hai?

Recall Solution

addw addition sirf low 32 bits par karta hai, 32 bits par wrap (modular) karta hai, phir 32-bit result ko 64 bits tak sign-extend karta hai.

  • x7 ke low 32 bits = 0x80000000.
  • ; low 32 rakho → 0x00000000.
  • 0x00000000 ko sign-extend karo (top bit 0) → 0x0000_0000_0000_0000. Answer: 0x0000000000000000 (yaani 0). 32 ke upar ka overflow bit simply drop ho jaata hai — exactly C ki int wraparound behavior.

L5.2

Abhi bhi RV64I. x7 mein 0x0000_0000_4000_0000 hai. addw x8, x7, x7 execute karo. Final 64-bit value?

Recall Solution
  • Low 32 bits = 0x40000000.
  • (32 bits mein fit hota hai, bit 31 ke baad koi overflow nahin).
  • 32-bit result 0x80000000 ka bit 31 = 1 hai → sign-extend upper 32 bits ko 1s se fill karta hai. Answer: 0xFFFFFFFF80000000. Yeh subtle case hai: koi 32-bit overflow nahin, lekin sign bit flip ho jaata hai, isliye 64-bit view negative ban jaata hai.

L5.3

J-type format (jo jal use karta hai) ek 20-bit immediate pack karta hai. Iska byte offset hai (20-bit signed value) × 2, yaani bit 0 implicit aur hamesha hai, exactly B-type branch ki tarah. Ek student claim karta hai ki jump bytes reach karta hai. Unhe correct karo aur true range do.

Recall Solution

Implicit bit-0 kahan se aata hai (same story as L2.3): instruction targets kam se kam 2-byte aligned hote hain (pure RV32I mein 4-byte aligned, 2-byte agar compressed C extension present ho), isliye target offset ka least-significant bit hamesha hota hai. Ek guaranteed zero par stored bit waste karne ke bajay, J-type offset ko 2 bytes ke units mein encode karta hai — hardware address reconstruct karte waqt implicit append karta hai. Toh 20 stored bits ek signed offset cover karte hain jise bytes mein padhne ke liye tum 2 se multiply karte ho: Student implicit-bit doubling bhool gaya. True reach: ±1 MiB, nahin ±512 KiB.

L5.4

Zero/degenerate check: beq x0, x0, target kya karta hai, aur kya yeh kabhi "not taken" hota hai?

Recall Solution

beq = branch if equal. x0 == x0 hamesha true hai (), isliye yeh branch unconditionally taken hoti hai, har baar. Yeh effectively ek unconditional relative jump hai (branch range ke andar). Isi tarah assemblers zero register use karke base instructions se ek chhota j/b (branch always) synthesize kar sakte hain — PC-relative targets ke liye Addressing Modes dekho.


Active recall (mixed)

Recall Quick self-quiz — answer karo, phir expand karo

RV64I mein register count? ::: 32 (RV32I jaisa; sirf width badlti hai). 12-bit immediate ki signed range? ::: . B-type branch ki byte reach? ::: KiB, 2-byte steps mein. addi x5, x6, -1 ka machine code? ::: 0xFFF30293. addw ka result jab 32-bit sum ka bit 31 set ho? ::: sign-extended → upper 32 bits saare 1s.