Day 53: Build the RV32I ISS (part 1): fetch / decode / execute
Build the RV32I ISS: fetch / decode / execute
An instruction-set simulator (ISS) is a program that *is* an RV32I CPU: it holds the 32 registers, PC, and a memory array, and loops fetch → decode → execute. It ignores timing and pipelining — it just computes the correct architectural result of each instruction. Crucially, this ISS is not a throwaway: in Stage 3 it becomes the golden reference model your RTL is checked against, instruction by instruction.
MASK = 0xFFFFFFFF
def sext(v, bits):
s = 1 << (bits - 1)
return (v ^ s) - s
class ISS:
def __init__(self, mem):
self.x = [0]*32 # x0..x31
self.pc = 0
self.mem = mem # bytearray
def step(self):
instr = self.fetch(self.pc)
op = instr & 0x7f
rd = (instr >> 7) & 0x1f
f3 = (instr >> 12) & 0x7
rs1 = (instr >> 15) & 0x1f
rs2 = (instr >> 20) & 0x1f
f7 = (instr >> 25) & 0x7f
nextpc = (self.pc + 4) & MASK
if op == 0x33: # R-type
a, b = self.x[rs1], self.x[rs2]
if f3 == 0 and f7 == 0x00: r = (a + b) & MASK # add
elif f3 == 0 and f7 == 0x20: r = (a - b) & MASK # sub
elif f3 == 7: r = a & b # and
elif f3 == 6: r = a | b # or
# ... xor, sll, srl, sra, slt, sltu ...
self.wr(rd, r)
elif op == 0x13: # I-type (addi, etc.)
imm = sext(instr >> 20, 12)
if f3 == 0: self.wr(rd, (self.x[rs1] + imm) & MASK) # addi
# ...
# ... loads, stores, branches (update nextpc), lui, auipc, jal, jalr ...
self.pc = nextpc
def wr(self, rd, val):
if rd != 0: self.x[rd] = val & MASK # x0 stays zeroYour decoder table, in code
The bit-slicing here is exactly your Day-37 hand-decoding, automated. Building it cements the encoding permanently and gives you a reference you *trust*, because you can single-step it and print registers. That trust is what makes it valuable as the Stage-3 scoreboard's oracle.
Key terms
- Instruction-set simulator
- A program that executes an ISA’s instructions for their architectural effect, ignoring timing.
- Golden reference model
- A trusted implementation used to check another (the RTL) against, instruction by instruction.
- Fetch/decode/execute
- The ISS loop: read the instruction, extract fields, perform its effect, advance PC.
- Sign extension (in code)
- Converting a narrow immediate to a full signed 32-bit value before use.
Progress for Day 53
Why is the ISS described as “not a throwaway”?