def __init__(self): super().__init__(RV32IXotbn) self.intreg = OTBNIntRegisterFile(32, 32, {0: 0}) self.wreg = RegisterFile(32, 256, {}, prefix="w") self.single_regs = {} self.single_regs["acc"] = SingleRegister(256, "ACC") self.single_regs["mod"] = SingleRegister(256, "MOD") self.flags = FlagGroups() self.loop_trace = [] self.loop = deque()
def __init__(self) -> None: super().__init__(RV32IXotbn) # Hack: this matches the superclass constructor, but you need it to # explain to mypy what self.pc is (because mypy can't peek into # riscvmodel without throwing up lots of errors) self.pc = Register(32) self.intreg = OTBNIntRegisterFile() self.wreg = RegisterFile(num=32, bits=256, immutable={}, prefix="w") self.single_regs = { 'acc': SingleRegister(256, "ACC"), 'mod': SingleRegister(256, "MOD") } self.flags = FlagGroups() self.loop_stack = LoopStack()
class OTBNState(State): # type: ignore def __init__(self) -> None: super().__init__(RV32IXotbn) # Hack: this matches the superclass constructor, but you need it to # explain to mypy what self.pc is (because mypy can't peek into # riscvmodel without throwing up lots of errors) self.pc = Register(32) self.intreg = OTBNIntRegisterFile() self.wreg = RegisterFile(num=32, bits=256, immutable={}, prefix="w") self.single_regs = { 'acc': SingleRegister(256, "ACC"), 'mod': SingleRegister(256, "MOD") } self.flags = FlagGroups() self.loop_stack = LoopStack() def csr_read(self, index: int) -> int: if index == 0x7C0: return int(self.wreg) elif 0x7D0 <= index <= 0x7D7: bit_shift = 32 * (index - 0x7D0) mask32 = (1 << 32) - 1 return (int(self.mod) >> bit_shift) & mask32 elif index == 0xFC0: return getrandbits(32) return cast(int, super().csr_read(self, index)) def wcsr_read(self, index: int) -> int: assert 0 <= index <= 2 if index == 0: return int(self.mod) elif index == 1: return getrandbits(256) else: assert index == 2 return int(self.single_regs['acc']) def wcsr_write(self, index: int, value: int) -> None: if index == 0: self.mod = value def loop_start(self, iterations: int, bodysize: int) -> None: next_pc = int(self.pc) + 4 skip_pc = self.loop_stack.start_loop(next_pc, bodysize, iterations) if skip_pc is not None: self.pc_update.set(skip_pc) def loop_step(self) -> None: back_pc = self.loop_stack.step(int(self.pc_update)) if back_pc is not None: self.pc = back_pc def changes(self) -> List[Trace]: c = cast(List[Trace], super().changes()) c += self.loop_stack.changes() c += self.wreg.changes() c += self.flags.changes() for name, reg in sorted(self.single_regs.items()): c += reg.changes() return c def commit(self) -> None: super().commit() self.loop_stack.commit() self.wreg.commit() self.flags.commit() for reg in self.single_regs.values(): reg.commit()
class OTBNState(State): def __init__(self): super().__init__(RV32IXotbn) self.intreg = OTBNIntRegisterFile(32, 32, {0: 0}) self.wreg = RegisterFile(32, 256, {}, prefix="w") self.single_regs = {} self.single_regs["acc"] = SingleRegister(256, "ACC") self.single_regs["mod"] = SingleRegister(256, "MOD") self.flags = FlagGroups() self.loop_trace = [] self.loop = deque() def __setattr__(self, name, value): if name in self.single_regs: self.single_regs[name].update(value) super().__setattr__(name, value) def __getattr__(self, name): if name in self.single_regs: return self.single_regs[name] return super().__getattribute__(name) def csr_read(self, index): if index == 0x7C0: return int(self.wreg) elif index == 0x7D0: return (int(self.mod) >> 0) & 0xffffffff elif index == 0x7D1: return (int(self.mod) >> 32) & 0xffffffff elif index == 0x7D2: return (int(self.mod) >> 64) & 0xffffffff elif index == 0x7D3: return (int(self.mod) >> 96) & 0xffffffff elif index == 0x7D4: return (int(self.mod) >> 128) & 0xffffffff elif index == 0x7D5: return (int(self.mod) >> 160) & 0xffffffff elif index == 0x7D6: return (int(self.mod) >> 192) & 0xffffffff elif index == 0x7D7: return (int(self.mod) >> 224) & 0xffffffff elif index == 0xFC0: return getrandbits(32) return super().csr_read(self, index) def wcsr_read(self, index): if index == 0: return int(self.mod) elif index == 1: return getrandbits(256) elif index == 2: return int(self.acc) def wcsr_write(self, index, value): old = None if index == 0: old = int(self.mod) self.mod = value return old def loop_start(self, iterations, bodysize): self.loop.appendleft({ "iterations": iterations, "bodysize": bodysize, "count_iterations": 0, "count_instructions": -1 }) self.loop_trace.append(TraceLoopStart(iterations, bodysize)) def changes(self): c = super().changes() if len(self.loop) > 0: if self.loop[0][ "count_instructions"] == self.loop[0]["bodysize"] - 1: self.loop_trace.append( TraceLoopIteration(self.loop[0]["count_iterations"] + 1, self.loop[0]["iterations"])) if self.loop[0][ "count_iterations"] == self.loop[0]["iterations"] - 1: self.loop.popleft() else: pc = self.pc - (self.loop[0]["bodysize"] - 1) * 4 self.pc_update = pc c.append(TracePC(pc)) self.loop[0]["count_iterations"] += 1 self.loop[0]["count_instructions"] = 0 else: self.loop[0]["count_instructions"] += 1 c += self.loop_trace c += self.wreg.changes() c += self.flags.changes() for reg in self.single_regs: c += self.single_regs[reg].changes() return c def commit(self): super().commit() self.wreg.commit() self.flags.commit() self.loop_trace.clear() for reg in self.single_regs: self.single_regs[reg].commit()