コード例 #1
0
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()
コード例 #2
0
ファイル: model.py プロジェクト: zarubaf/opentitan
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()