# Register block of RV32I # Set and get using [] with the name of the register (lowercase) or the # position from ctypes import c_uint32 def defaultGetter(self, pos): return self.data[pos] def defaultSetter(self, pos, val): self.data[pos] = val def zeroSetter(self, pos, val): # hardwired to zero self.data[pos] = c_uint32(0) class RegistersRV32I: def __init__(self): self.names = {} self.data = [] self.setter = [] self.getter = [] self.lastChange = None self.addRegister(("x0","zero"), setter = zeroSetter) self.addRegister(("x1","ra")) self.addRegister(("x2","sp", "v0")) self.addRegister(("x3","gp", "v1")) self.addRegister(("x4","tp")) self.addRegister(("x5","t0")) self.addRegister(("x6","t1")) self.addRegister(("x7","t2")) self.addRegister(("x8","s0","fp")) self.addRegister(("x9","s1")) self.addRegister(("x10","a0")) self.addRegister(("x11","a1")) self.addRegister(("x12","a2")) self.addRegister(("x13","a3")) self.addRegister(("x14","a4")) self.addRegister(("x15","a5")) self.addRegister(("x16","a6")) self.addRegister(("x17","a7")) self.addRegister(("x18","s2")) self.addRegister(("x19","s3")) self.addRegister(("x20","s4")) self.addRegister(("x21","s5")) self.addRegister(("x22","s6")) self.addRegister(("x23","s7")) self.addRegister(("x24","s8")) self.addRegister(("x25","s9")) self.addRegister(("x26","s10")) self.addRegister(("x27","s11")) self.addRegister(("x28","t3")) self.addRegister(("x29","t4")) self.addRegister(("x30","t5")) self.addRegister(("x31","t6")) def addRegister(self, names, getter=defaultGetter, setter=defaultSetter): for name in names: if name in self.names: raise KeyError("Register name already in use") currentpos = len(self.data) for name in names: self.names[name] = currentpos self.data.append(c_uint32(0)) self.getter.append(getter) self.setter.append(setter) def getPos(self, el): if isinstance(el, str): pos = self.names[el] elif isinstance(el, int): pos = el else: raise ValueError("Wrong type of register id. Must be str or int") return pos def __getitem__(self, el): pos = self.getPos(el) return self.getter[pos](self, pos) def __setitem__(self, el, val): pos = self.getPos(el) if val > 0xFFFFFFFF: raise ValueError("Value is larger than size of the register") val = c_uint32(val) self.setter[pos](self, pos, val) self.lastChange = pos def __str__(self): out = " " out += "-" * 67 out += "\n" for i,d in enumerate(self.data): out += "->" if i == self.lastChange else " " out += f" | {d.value:#13} | {d.value:#010x} | {d.value:#034b} |" out += "\n" out += " " out += "-" * 67 out += "\n" return out if __name__ == "__main__": Regs = RegistersRV32I() Regs[0] = 1 Regs["x1"] = 10 print(Regs)