diff options
Diffstat (limited to 'pysc-v/registers/RV32I.py')
-rw-r--r-- | pysc-v/registers/RV32I.py | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/pysc-v/registers/RV32I.py b/pysc-v/registers/RV32I.py new file mode 100644 index 0000000..4652bca --- /dev/null +++ b/pysc-v/registers/RV32I.py @@ -0,0 +1,116 @@ +# 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")) + self.addRegister(("x3","gp")) + 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): + return self.getter[self.getPos(el)](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) |