#
# Copyright (C) [2020] Futurewei Technologies, Inc.
#
# FORCE-RISCV is licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR
# FIT FOR A PARTICULAR PURPOSE.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from riscv.EnvRISCV import EnvRISCV
from riscv.GenThreadRISCV import GenThreadRISCV
from base.Sequence import Sequence
from DV.riscv.instruction_list import instructions
import state_transition_test_utils
from Enums import EStateElementType
from State import State
import RandomUtils
import StateTransition

## This test verifies that StateTransitions yield the expected State with a wide variety of
# interleaved instructions.
class MainSequence(Sequence):

    def __init__(self, aGenThread, aName=None):
        super().__init__(aGenThread, aName)

        self._mExpectedStateData = {}

    def generate(self, **kargs):
        for _ in range(3):
            state = self._createState()

            self._genRandomInstructions()

            StateTransition.transitionToState(state)
            state_transition_test_utils.verifyState(self, self._mExpectedStateData)

            self._genRandomInstructions()

    ## Generate a random number of a wide variety of instructions.
    def _genRandomInstructions(self):
        for _ in range(RandomUtils.random32(100, 200)):
            instr = self.choice(instructions)

            # TODO(Noah): Permit instructions that begin with E and F when exception handlers are
            # implemented. The excluded instructions, EBREAK, ECALL and floating point instructions,
            # are generally prone to triggering exceptions.
            if not (instr.startswith('E') or instr.startswith('F')):
                self.genInstruction(instr)

    ## Create a random State to test an explicit StateTransition.
    def _createState(self):
        state = State()

        self._mExpectedStateData[EStateElementType.Memory] = state_transition_test_utils.addRandomMemoryStateElements(self, state, RandomUtils.random32(0, 20))
        self._mExpectedStateData[EStateElementType.GPR] = state_transition_test_utils.addRandomGprStateElements(self, state, RandomUtils.random32(0, 20))
        self._mExpectedStateData[EStateElementType.FloatingPointRegister] = state_transition_test_utils.addRandomFloatingPointRegisterStateElements(self, state, RandomUtils.random32(0, 20))
        self._mExpectedStateData[EStateElementType.PC] = state_transition_test_utils.addRandomPcStateElement(self, state)

        return state


MainSequenceClass = MainSequence
GenThreadClass = GenThreadRISCV
EnvClass = EnvRISCV


#
# Copyright (C) [2020] Futurewei Technologies, Inc.
#
# FORCE-RISCV is licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR
# FIT FOR A PARTICULAR PURPOSE.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from riscv.EnvRISCV import EnvRISCV
from riscv.GenThreadRISCV import GenThreadRISCV
from base.Sequence import Sequence
from DV.riscv.instruction_list import instructions
import state_transition_test_utils
from Enums import EStateElementType
from State import State
import RandomUtils
import StateTransition

## This test verifies that StateTransitions yield the expected State with a wide variety of
# interleaved instructions.
class MainSequence(Sequence):

    def __init__(self, aGenThread, aName=None):
        super().__init__(aGenThread, aName)

        self._mExpectedStateData = {}

    def generate(self, **kargs):
        for _ in range(3):
            state = self._createState()

            self._genRandomInstructions()

            StateTransition.transitionToState(state)
            state_transition_test_utils.verifyState(self, self._mExpectedStateData)

            self._genRandomInstructions()

    ## Generate a random number of a wide variety of instructions.
    def _genRandomInstructions(self):
        for _ in range(RandomUtils.random32(100, 200)):
            instr = self.choice(instructions)

            # TODO(Noah): Permit instructions that begin with E and F when exception handlers are
            # implemented. The excluded instructions, EBREAK, ECALL and floating point instructions,
            # are generally prone to triggering exceptions.
            if not (instr.startswith('E') or instr.startswith('F')):
                self.genInstruction(instr)

    ## Create a random State to test an explicit StateTransition.
    def _createState(self):
        state = State()

        self._mExpectedStateData[EStateElementType.Memory] = state_transition_test_utils.addRandomMemoryStateElements(self, state, RandomUtils.random32(0, 20))
        self._mExpectedStateData[EStateElementType.GPR] = state_transition_test_utils.addRandomGprStateElements(self, state, RandomUtils.random32(0, 20))
        self._mExpectedStateData[EStateElementType.FloatingPointRegister] = state_transition_test_utils.addRandomFloatingPointRegisterStateElements(self, state, RandomUtils.random32(0, 20))
        self._mExpectedStateData[EStateElementType.PC] = state_transition_test_utils.addRandomPcStateElement(self, state)

        return state


MainSequenceClass = MainSequence
GenThreadClass = GenThreadRISCV
EnvClass = EnvRISCV


# # Copyright (C) [2020] Futurewei Technologies, Inc. # # FORCE-RISCV is licensed under the Apache License, Version 2.0 (the "License"); #  you may not use this file except in compliance with the License. #  You may obtain a copy of the License at # #  http://www.apache.org/licenses/LICENSE-2.0 # # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR # FIT FOR A PARTICULAR PURPOSE. # See the License for the specific language governing permissions and # limitations under the License. # ## This test verifies that StateTransitions yield the expected State with a wide variety of # interleaved instructions. ## Generate a random number of a wide variety of instructions. # TODO(Noah): Permit instructions that begin with E and F when exception handlers are # implemented. The excluded instructions, EBREAK, ECALL and floating point instructions, # are generally prone to triggering exceptions. ## Create a random State to test an explicit StateTransition.