blob: c89938c1acb7a81038da72f311b7ef219391de1a [file] [log] [blame]
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
from itertools import cycle
from typing import Optional, TextIO
from .sim import OTBNSim
_TEST_RND_DATA = cycle([
0xAAAAAAAA_99999999_AAAAAAAA_99999999_AAAAAAAA_99999999_AAAAAAAA_99999999,
0xCCCCCCCC_BBBBBBBB_CCCCCCCC_BBBBBBBB_CCCCCCCC_BBBBBBBB_CCCCCCCC_BBBBBBBB,
])
# This is the default seed for URND PRNG. Note that the actualy URND value will
# be random since we are modelling PRNG inside the URND register model.
_TEST_URND_DATA = [
0x84ddfadaf7e1134d, 0x70aa1c59de6197ff,
0x25a4fe335d095f1e, 0x2cba89acbe4a07e9
]
class StandaloneSim(OTBNSim):
def run(self, verbose: bool, dump_file: Optional[TextIO]) -> int:
'''Run until ECALL.
Return the number of cycles taken.
'''
insn_count = 0
# ISS will stall at start until URND data is valid; immediately set it
# valid when in free running mode as nothing else will.
self.state.wsrs.URND.set_seed(_TEST_URND_DATA)
# Similarly, set the initial secure wipe to complete.
self.state.complete_init_sec_wipe()
while self.state.executing():
# If there's a RND request, respond immediately
if self.state.ext_regs.read('RND_REQ', True):
self.state.wsrs.RND.set_unsigned(next(_TEST_RND_DATA), False,
False)
# If there's a URND request, respond immediately.
if not self.state.wsrs.URND.running:
self.state.wsrs.URND.set_seed(_TEST_URND_DATA)
self.step(verbose)
insn_count += 1
# Dump registers on the first wipe cycle. This makes sure that we
# dump them before zeroing.
if dump_file is not None and self.state.wiping():
self.dump_regs(dump_file)
dump_file = None
return insn_count
def dump_regs(self, tgt: TextIO) -> None:
for reg in ['ERR_BITS', 'INSN_CNT', 'STOP_PC']:
value = self.state.ext_regs.read(reg, False)
tgt.write(' {} = 0x{:08x}\n'.format(reg, value))
for idx, value in enumerate(self.state.gprs.peek_unsigned_values()):
tgt.write(' x{:<2} = 0x{:08x}\n'.format(idx, value))
for idx, value in enumerate(self.state.wdrs.peek_unsigned_values()):
tgt.write(' w{:<2} = 0x{:064x}\n'.format(idx, value))