def generate(self, **kargs):
        init_size = 256
        init_addr = self.genVA(Size=init_size, Align=init_size, Type="D")
        addr_constr = ConstraintSet(init_addr, (init_addr + init_size - 1))

        for _ in range(RandomUtils.random32(50, 100)):
            size = RandomUtils.random32(8, 32)
            alignment = self.choice((1, 2, 4, 8, 16, 32))
            addr = self.genVA(Size=size,
                              Align=alignment,
                              Type="D",
                              Range=str(addr_constr))

            if not addr_constr.containsValue(addr):
                self.error("Virtual address 0x%x was generated outside of the "
                           "specified range %s" % (addr, addr_constr))
示例#2
0
    def generate(self, **kargs):
        init_size = 256
        init_addr = self.genVA(Size=init_size, Align=init_size, Type='D')
        addr_constr = ConstraintSet(init_addr, (init_addr + init_size - 1))

        for _ in range(RandomUtils.random32(50, 100)):
            instr_params = {'LSTarget': str(addr_constr), 'NoSkip': 1}

            if RandomUtils.random32(0, 1) == 1:
                instr_params['NoPreamble'] = 1
            else:
                instr_params['UsePreamble'] = 1

            instr_id = self.genInstruction(
                self.choice(('LD##RISCV', 'SD##RISCV')), instr_params)
            instr_record = self.queryInstructionRecord(instr_id)
            if not addr_constr.containsValue(instr_record['LSTarget']):
                self.error(
                    'Target address 0x%x was generated outside of the specified range %s'
                    % (addr, addr_constr))
示例#3
0
    def generate(self, **kargs):
        init_size = 256
        init_addr = self.genVA(Size=init_size, Align=init_size, Type="D")
        addr_constr = ConstraintSet(init_addr, (init_addr + init_size - 1))

        for _ in range(RandomUtils.random32(50, 100)):
            instr_params = {"LSTarget": str(addr_constr), "NoSkip": 1}

            if RandomUtils.random32(0, 1) == 1:
                instr_params["NoPreamble"] = 1
            else:
                instr_params["UsePreamble"] = 1

            if self.getGlobalState("AppRegisterWidth") == 32:
                instr_id = self.genInstruction(
                    self.choice(("LW##RISCV", "SW##RISCV")), instr_params)
            else:
                instr_id = self.genInstruction(
                    self.choice(("LD##RISCV", "SD##RISCV")), instr_params)

            instr_record = self.queryInstructionRecord(instr_id)
            if not addr_constr.containsValue(instr_record["LSTarget"]):
                self.error("Target address 0x%x was generated outside of the"
                           "specified range %s" % (addr, addr_constr))
示例#4
0
class VectorLoadStoreTestSequence(VectorTestSequence):
    def __init__(self, aGenThread, aName=None):
        super().__init__(aGenThread, aName)

        self._mUnalignedAllowed = False
        self._mTargetAddrConstr = None

    # Set up the environment prior to generating the test instructions.
    def _setUpTest(self):
        if RandomUtils.random32(0, 1) == 1:
            choices_mod = ChoicesModifier(self.genThread)
            choice_weights = {"Aligned": 80, "Unaligned": 20}
            choices_mod.modifyOperandChoices("Data alignment", choice_weights)
            choices_mod.commitSet()
            self._mUnalignedAllowed = True

    # Return parameters to be passed to Sequence.genInstruction().
    def _getInstructionParameters(self):
        self._mTargetAddrConstr = None
        instr_params = {}
        if RandomUtils.random32(0, 1) == 1:
            if RandomUtils.random32(0, 1) == 1:
                instr_params["NoPreamble"] = 1

            target_choice = RandomUtils.random32(0, 2)
            if target_choice == 1:
                target_addr = self.genVA(Size=512, Align=8, Type="D")
                self._mTargetAddrConstr = ConstraintSet(target_addr)
                instr_params["LSTarget"] = str(self._mTargetAddrConstr)
            elif target_choice == 2:
                va_range_size = RandomUtils.random32()
                min_target_addr = self.genVA(Size=512, Align=8, Type="D")
                max_target_addr = mask_to_size(
                    (min_target_addr + RandomUtils.random32()), 64)
                self._mTargetAddrConstr = ConstraintSet(
                    min_target_addr, max_target_addr)
                instr_params["LSTarget"] = str(self._mTargetAddrConstr)

        return instr_params

    # Return true if it is permissible for the generation to skip this
    # instruction.
    #
    #  @param aInstr The name of the instruction.
    #  @param aInstrParams The parameters passed to Sequence.genInstruction().
    def _isSkipAllowed(self, aInstr, aInstrParams):
        if aInstrParams or (self._calculateEmul(aInstr) > 8):
            return True

        return False

    # Verify additional aspects of the instruction generation and execution.
    #
    #  @param aInstr The name of the instruction.
    #  @param aInstrRecord A record of the generated instruction.
    def _performAdditionalVerification(self, aInstr, aInstrRecord):
        if ((self._mTargetAddrConstr is not None)
                and (0x2 not in self._getAllowedExceptionCodes(aInstr))
                and (not self._mTargetAddrConstr.containsValue(
                    aInstrRecord["LSTarget"]))):
            self.error("Target address 0x%x was outside of the specified "
                       "constraint %s" %
                       (aInstrRecord["LSTarget"], self._mTargetAddrConstr))

    # Get allowed exception codes.
    #
    #  @param aInstr The name of the instruction.
    def _getAllowedExceptionCodes(self, aInstr):
        allowed_except_codes = set()
        if self._mUnalignedAllowed:
            allowed_except_codes.add(0x4)
            allowed_except_codes.add(0x6)

        if self._calculateEmul(aInstr) > 8:
            allowed_except_codes.add(0x2)

        return allowed_except_codes

    # Calculate EMUL for the given instruction.
    #
    #  @param aInstr The name of the instruction.
    def _calculateEmul(self, aInstr):
        eew = self._getEew(aInstr)

        (vlmul_val, valid) = self.readRegister("vtype", field="VLMUL")
        self.assertValidRegisterValue("vtype", valid)
        lmul = self.calculateLmul(vlmul_val)

        (vsew_val, valid) = self.readRegister("vtype", field="VSEW")
        self.assertValidRegisterValue("vtype", valid)
        sew = self.calculateLmul(vsew_val)

        return round((eew / sew) * lmul)

    # Determine EEW for the given instruction.
    #
    #  @param aInstr The name of the instruction.
    def _getEew(self, aInstr):
        match = re.fullmatch(r"V[A-Z]+(\d+)\.V\#\#RISCV", aInstr)
        return int(match.group(1))
示例#5
0
class VectorLoadStoreTestSequence(VectorTestSequence):
    def __init__(self, aGenThread, aName=None):
        super().__init__(aGenThread, aName)

        self._mUnalignedAllowed = False
        self._mTargetAddrConstr = None

    ## Set up the environment prior to generating the test instructions.
    def _setUpTest(self):
        if RandomUtils.random32(0, 1) == 1:
            choices_mod = ChoicesModifier(self.genThread)
            choice_weights = {'Aligned': 80, 'Unaligned': 20}
            choices_mod.modifyOperandChoices('Data alignment', choice_weights)
            choices_mod.commitSet()
            self._mUnalignedAllowed = True

    ## Return parameters to be passed to Sequence.genInstruction().
    def _getInstructionParameters(self):
        self._mTargetAddrConstr = None
        instr_params = {}
        if RandomUtils.random32(0, 1) == 1:
            if RandomUtils.random32(0, 1) == 1:
                instr_params['NoPreamble'] = 1

            target_choice = RandomUtils.random32(0, 2)
            if target_choice == 1:
                target_addr = self.genVA(Size=512, Align=8, Type='D')
                self._mTargetAddrConstr = ConstraintSet(target_addr)
                instr_params['LSTarget'] = str(self._mTargetAddrConstr)
            elif target_choice == 2:
                va_range_size = RandomUtils.random32()
                min_target_addr = self.genVA(Size=512, Align=8, Type='D')
                max_target_addr = mask_to_size(
                    (min_target_addr + RandomUtils.random32()), 64)
                self._mTargetAddrConstr = ConstraintSet(
                    min_target_addr, max_target_addr)
                instr_params['LSTarget'] = str(self._mTargetAddrConstr)

        return instr_params

    ## Return true if it is permissible for the generation to skip this instruction.
    #
    #  @param aInstr The name of the instruction.
    #  @param aInstrParams The parameters passed to Sequence.genInstruction().
    def _isSkipAllowed(self, aInstr, aInstrParams):
        if aInstrParams or (self._calculateEmul(aInstr) > 8):
            return True

        return False

    ## Verify additional aspects of the instruction generation and execution.
    #
    #  @param aInstr The name of the instruction.
    #  @param aInstrRecord A record of the generated instruction.
    def _performAdditionalVerification(self, aInstr, aInstrRecord):
        if (self._mTargetAddrConstr
                is not None) and (not self._mTargetAddrConstr.containsValue(
                    aInstrRecord['LSTarget'])):
            self.error(
                'Target address 0x%x was outside of the specified constraint %s'
                % (aInstrRecord['LSTarget'], self._mTargetAddrConstr))

    ## Get allowed exception codes.
    #
    #  @param aInstr The name of the instruction.
    def _getAllowedExceptionCodes(self, aInstr):
        allowed_except_codes = set()
        if self._mUnalignedAllowed:
            allowed_except_codes.add(0x4)
            allowed_except_codes.add(0x6)

        if self._calculateEmul(aInstr) > 8:
            allowed_except_codes.add(0x2)

        # TODO(Noah): Remove the line below permitting store page fault exceptions when the page
        # descriptor generation is improved. Currently, we are generating read-only pages for load
        # instructions, which is causing subsequent store instructions to the same page to fault.
        allowed_except_codes.add(0xF)

        return allowed_except_codes

    ## Calculate EMUL for the given instruction.
    #
    #  @param aInstr The name of the instruction.
    def _calculateEmul(self, aInstr):
        eew = self._getEew(aInstr)

        (vlmul_val, valid) = self.readRegister('vtype', field='VLMUL')
        self.assertValidRegisterValue('vtype', valid)
        lmul = self.calculateLmul(vlmul_val)

        (vsew_val, valid) = self.readRegister('vtype', field='VSEW')
        self.assertValidRegisterValue('vtype', valid)
        sew = self.calculateLmul(vsew_val)

        return round((eew / sew) * lmul)

    ## Determine EEW for the given instruction.
    #
    #  @param aInstr The name of the instruction.
    def _getEew(self, aInstr):
        match = re.fullmatch(r'V[A-Z]+(\d+)\.V\#\#RISCV', aInstr)
        return int(match.group(1))