def _createMemoryStateElements(self, aState): expected_mem_state_data = set() for _ in range(RandomUtils.random32(0, 5)): mem_size = RandomUtils.random32(1, 20) mem_start_addr = self.genVA(Size=mem_size, Align=1, Type="D") mem_values = [] for _ in range(mem_size): mem_values.append(RandomUtils.random32(0, 0xFF)) aState.addMemoryStateElementsAsBytes(mem_start_addr, mem_values) # Compute the start addresses for the resulting StateElements state_elem_size = 8 aligned_mem_start_addr = UtilityFunctions.getAlignedValue( mem_start_addr, state_elem_size) bytes_remaining = mem_size chunk_size = state_elem_size - (mem_start_addr - aligned_mem_start_addr) while bytes_remaining > 0: expected_mem_state_data.add(aligned_mem_start_addr) aligned_mem_start_addr += state_elem_size bytes_remaining -= chunk_size # The last StateElement may contain fewer specified bytes than # state_elem_size, but setting chunk_size to state_elem_size # will cause the loop to terminate at the correct time in # either case chunk_size = state_elem_size return expected_mem_state_data
def createState(self): state = State() # Get a random 4-byte virtual address as a target PC value pc_val = self.genVA(Size=4, Align=4, Type="I") state.addPcStateElement(pc_val) # Add half of the floating point registers here and half of the # floating point registers below. This helps demonstrate how the # transition logic consolidates the elements by type regardless of the # order in which they were specified. fp_reg_indices = self.getRandomRegisters(6, reg_type="FPR") for i in range(0, 3): fp_reg_index = fp_reg_indices[i] fp_reg_name = "D%d" % fp_reg_index state.addRegisterStateElement( fp_reg_name, [RandomUtils.random64()] ) state.addRegisterStateElement("mscratch", [RandomUtils.random64()]) mepc_val = UtilityFunctions.getAlignedValue(RandomUtils.random64(), 4) state.addRegisterStateElement("mepc", [mepc_val]) for i in range(3, 6): fp_reg_index = fp_reg_indices[i] fp_reg_name = "D%d" % fp_reg_index state.addRegisterStateElement( fp_reg_name, [RandomUtils.random64()] ) return state
def _createVectorRegisterStateElements(self, aState): expected_vec_reg_state_data = {} vec_reg_count = RandomUtils.random32(0, 10) vec_reg_indices = self.sample(range(0, 32), vec_reg_count) max_reg_val_count = self.getLimitValue("MaxPhysicalVectorLen") // 64 for vec_reg_index in vec_reg_indices: vec_reg_values = [] state_elem_reg_val_count = RandomUtils.random32( 1, max_reg_val_count) for val_index in range(state_elem_reg_val_count): vec_reg_values.append(RandomUtils.random64()) vec_reg_name = "v%d" % vec_reg_index self.randomInitializeRegister(vec_reg_name) aState.addRegisterStateElement(vec_reg_name, vec_reg_values) for val_index in range(state_elem_reg_val_count, max_reg_val_count): field_name = "%s_%d" % (vec_reg_name, val_index) (field_val, valid) = self.readRegister(vec_reg_name, field=field_name) utils.assert_valid_register_value(self, vec_reg_name, valid) vec_reg_values.append(field_val) expected_vec_reg_state_data[vec_reg_name] = vec_reg_values return expected_vec_reg_state_data
def add_random_floating_point_register_state_elements(aSequence, aState, aStateElemCount, aPriorityMin=1, aPriorityMax=100): expected_fp_reg_state_data = [] fp_reg_indices = aSequence.sample(range(0, 32), aStateElemCount) for fp_reg_index in fp_reg_indices: # NOTE: utility used to move gpr reg values to fp regs doesn't work # with double precision in 32-bit mode... fp_reg_name_prefix = aSequence.choice(("S", "D")) fp_reg_name = "%s%d" % (fp_reg_name_prefix, fp_reg_index) if fp_reg_name_prefix == "S": fp_reg_val = UtilityFunctions.signExtend64(RandomUtils.random32(), 64) else: fp_reg_val = RandomUtils.random64() aState.addRegisterStateElement( fp_reg_name, (fp_reg_val, ), aPriority=RandomUtils.random32(aPriorityMin, aPriorityMax), ) expected_fp_reg_state_data.append((fp_reg_name, fp_reg_val)) return expected_fp_reg_state_data
def generate(self, **kargs): for _ in range(50): size_bits = RandomUtils.random32(1, 20) size = 2**size_bits align_bits = RandomUtils.random32(1, size_bits) align = 2**align_bits arch_mem_attr = self.choice( ("MainRegion", "IORegion", "CacheableShared", "Uncacheable")) impl_mem_attr = self.choice( ("DMA Controller", "UART 0", "UART 1", "DDR Control")) start_addr = self.genPA( Size=size, Align=align, Type="D", MemAttrArch=arch_mem_attr, MemAttrImpl=impl_mem_attr, ) end_addr = start_addr + size - 1 if not MemoryTraits.hasMemoryAttribute(arch_mem_attr, start_addr, end_addr): self.error( "Memory attribute %s not assigned to physical address range 0x%x-0x%x" % (arch_mem_attr, start_addr, end_addr)) if not MemoryTraits.hasMemoryAttribute(impl_mem_attr, start_addr, end_addr): self.error( "Memory attribute %s not assigned to physical address range 0x%x-0x%x" % (impl_mem_attr, start_addr, end_addr))
def generate(self, **kargs): state_trans_handler = GprBootStateTransitionHandlerTest(self.genThread) StateTransition.registerStateTransitionHandler( state_trans_handler, EStateTransitionType.Boot, (EStateElementType.GPR, )) gpr_indices = self.getRandomGPRs(RandomUtils.random32(2, 15), exclude='0') state_trans_handler.mMemBlockPtrIndex = gpr_indices[0] state_trans_handler.mGprIndices = set(gpr_indices[1:]) # Initialize a memory block for the StateTransitionHandler to use to load the GPR boot # values mem_block_size = 32 * 8 mem_block_start_addr = self.genVA(Size=mem_block_size, Align=8, Type='D') self.initializeRegister(('x%d' % gpr_indices[0]), mem_block_start_addr) state_trans_handler.mMemBlockStartAddr = mem_block_start_addr for gpr_index in gpr_indices[1:]: gpr_entry_addr = mem_block_start_addr + gpr_index * 8 gpr_val = RandomUtils.random64() self.initializeMemory(addr=gpr_entry_addr, bank=0, size=8, data=gpr_val, is_instr=False, is_virtual=True) self.initializeRegister(('x%d' % gpr_index), gpr_val) instructions = ('ADD##RISCV', 'ADDW##RISCV', 'LD##RISCV', 'LUI##RISCV', 'SD##RISCV', 'SLLI#RV64I#RISCV', 'SRLI#RV64I#RISCV') for _ in range(RandomUtils.random32(100, 200)): self.genInstruction(self.choice(instructions))
def _verifyRandomStackOperations(self, aStack): for _ in range(RandomUtils.random32(50, 100)): gpr_index = self.getRandomGPR(exclude=('0,%d' % aStack.pointerIndex())) gpr_val = self._loadRandomizedGprValue(gpr_index) operation = 'push' if not self._isStackEmpty(aStack): operation = self.choice(('push', 'pop', 'peek', 'modify')) if operation == 'push': self._mReferenceStack.append(gpr_val) aStack.push(gpr_index) elif operation == 'pop': aStack.pop(gpr_index) exception_handlers_test_utils.assertGprHasValue( self, gpr_index, self._mReferenceStack.pop()) # Stack items are indexed using the aOffset parameter from 0 at the top to size - 1 at # the bottom elif operation == 'peek': max_stack_index = len(self._mReferenceStack) - 1 stack_index = RandomUtils.random32(0, max_stack_index) aStack.peek(gpr_index, aOffset=stack_index) exception_handlers_test_utils.assertGprHasValue( self, gpr_index, self._mReferenceStack[max_stack_index - stack_index]) elif operation == 'modify': max_stack_index = len(self._mReferenceStack) - 1 stack_index = RandomUtils.random32(0, max_stack_index) self._mReferenceStack[stack_index] = gpr_val aStack.modify(gpr_index, aOffset=(max_stack_index - stack_index)) else: self.error('Unexpected stack operation %s' % operation)
def _createState(self): state = State() expected_mem_state_data = [] mem_block_size = RandomUtils.random32(0x8, 0x20) * 16 self._mMemBlockStartAddr = self.genVA(Size=mem_block_size, Align=16, Type="D") self._mMemBlockEndAddr = self._mMemBlockStartAddr + mem_block_size - 1 cur_addr = self._mMemBlockStartAddr while cur_addr <= self._mMemBlockEndAddr: if self.getGlobalState("AppRegisterWidth") == 32: mem_val = RandomUtils.random32() state.addMemoryStateElement(cur_addr, 4, mem_val) expected_mem_state_data.append((cur_addr, mem_val)) cur_addr += 4 else: mem_val = RandomUtils.random64() state.addMemoryStateElement(cur_addr, 8, mem_val) expected_mem_state_data.append((cur_addr, mem_val)) cur_addr += 8 self._mExpectedStateData[ EStateElementType.Memory] = expected_mem_state_data return state
def _createStateC(self): state = State() self._mExpectedStateData = {} expected_sys_reg_state_data = [] fcsr_name = 'fcsr' state.addSystemRegisterStateElementByField(fcsr_name, 'FRM', 1) (fcsr_val, valid) = self.readRegister(fcsr_name) state_transition_test_utils.assertValidRegisterValue( self, fcsr_name, valid) fcsr_val = state_transition_test_utils.combineRegisterValueWithFieldValue( self, fcsr_name, fcsr_val, 'FRM', 1) # TODO(Noah): Enable verification of setting the fcsr register when the readRegister() # method reads the correct value for fcsr. Currently, the top 58 bits are being initialized # to a non-zero value by Force, which is not legal. #expected_sys_reg_state_data.append((fcsr_name, fcsr_val)) expected_fp_reg_state_data = [] for fp_reg_index in range(0, 32): fp_reg_val = RandomUtils.random64(0, 0x3FFFFFFFFFFFFFFF) state.addRegisterStateElement(('D%d' % fp_reg_index), (fp_reg_val, )) self._mExpectedStateData[ EStateElementType. FloatingPointRegister] = expected_fp_reg_state_data sstatus_name = 'sstatus' fs_val = RandomUtils.random32(1, 3) state.addSystemRegisterStateElementByField(sstatus_name, 'FS', fs_val) (sstatus_val, valid) = self.readRegister(sstatus_name) state_transition_test_utils.assertValidRegisterValue( self, sstatus_name, valid) sstatus_val = state_transition_test_utils.combineRegisterValueWithFieldValue( self, sstatus_name, sstatus_val, 'FS', fs_val) # Adjust expected value of SD bit according to architecture rules (xs_val, valid) = self.readRegister(sstatus_name, field='XS') state_transition_test_utils.assertValidRegisterValue( self, sstatus_name, valid) (vs_val, valid) = self.readRegister(sstatus_name, field='VS') state_transition_test_utils.assertValidRegisterValue( self, sstatus_name, valid) if (fs_val == 3) or (xs_val == 3) or (vs_val == 3): sstatus_val = state_transition_test_utils.combineRegisterValueWithFieldValue( self, sstatus_name, sstatus_val, 'SD', 1) else: sstatus_val = state_transition_test_utils.combineRegisterValueWithFieldValue( self, sstatus_name, sstatus_val, 'SD', 0) expected_sys_reg_state_data.append((sstatus_name, sstatus_val)) self._mExpectedStateData[ EStateElementType.SystemRegister] = expected_sys_reg_state_data return state
def addRandomMemoryStateElements(aSequence, aState, aStateElemCount, aPriorityMin=1, aPriorityMax=100): expected_mem_state_data = [] for _ in range(aStateElemCount): mem_start_addr = aSequence.genVA(Size=8, Align=8, Type='D') mem_val = RandomUtils.random64() aState.addMemoryStateElement(mem_start_addr, 8, mem_val, aPriority=RandomUtils.random32(aPriorityMin, aPriorityMax)) expected_mem_state_data.append((mem_start_addr, mem_val)) return expected_mem_state_data
def generate(self, **kargs): state_trans_handler = GprBootStateTransitionHandlerTest(self.genThread) StateTransition.registerStateTransitionHandler( state_trans_handler, EStateTransitionType.Boot, (EStateElementType.GPR, ), ) gpr_indices = self.getRandomGPRs(RandomUtils.random32(2, 15), exclude="0") state_trans_handler.mMemBlockPtrIndex = gpr_indices[0] state_trans_handler.mGprIndices = set(gpr_indices[1:]) # Initialize a memory block for the StateTransitionHandler to use to # load the GPR boot values mem_block_size = 32 * 8 mem_block_start_addr = self.genVA(Size=mem_block_size, Align=8, Type="D") self.initializeRegister(("x%d" % gpr_indices[0]), mem_block_start_addr) state_trans_handler.mMemBlockStartAddr = mem_block_start_addr for gpr_index in gpr_indices[1:]: gpr_entry_addr = mem_block_start_addr + gpr_index * 8 gpr_val = RandomUtils.random64() self.initializeMemory( addr=gpr_entry_addr, bank=0, size=8, data=gpr_val, is_instr=False, is_virtual=True, ) self.initializeRegister(("x%d" % gpr_index), gpr_val) if self.getGlobalState("AppRegisterWidth") == 32: instructions = ( "ADD##RISCV", "LW##RISCV", "LUI##RISCV", "SW##RISCV", "SLLI#RV32I#RISCV", "SRLI#RV32I#RISCV", ) else: instructions = ( "ADD##RISCV", "ADDW##RISCV", "LD##RISCV", "LUI##RISCV", "SD##RISCV", "SLLI#RV64I#RISCV", "SRLI#RV64I#RISCV", ) for _ in range(RandomUtils.random32(100, 200)): self.genInstruction(self.choice(instructions))
def _createState(self): state = State() gpr_indices = self.getRandomGPRs(RandomUtils.random32(0, 15), exclude="0") for gpr_index in gpr_indices: state.addRegisterStateElement(("x%d" % gpr_index), (RandomUtils.random64(),)) self._mSpecGprIndices = self._mSpecGprIndices.union(gpr_indices) return state
def addRandomGprStateElements(aSequence, aState, aStateElemCount, aPriorityMin=1, aPriorityMax=100): expected_gpr_state_data = [] gpr_indices = aSequence.getRandomGPRs(aStateElemCount, exclude='0') for gpr_index in gpr_indices: gpr_name = 'x%d' % gpr_index gpr_val = RandomUtils.random64() aState.addRegisterStateElement(gpr_name, (gpr_val,), aPriority=RandomUtils.random32(aPriorityMin, aPriorityMax)) expected_gpr_state_data.append((gpr_name, gpr_val)) return expected_gpr_state_data
def _verifyRandomStackFrameOperations(self, aStack): for _ in range(RandomUtils.random32(10, 20)): operation = "" if not self._mReferenceStackFrames: operation = "newStackFrame" else: operation = self.choice( ("newStackFrame", "freeStackFrame", "arg", "modifyArg")) if operation == "newStackFrame": # The link register x1 is automatically captured in every # stack frame, so we exclude it to avoid capturing it twice in # the same frame. gpr_indices = self.getRandomGPRs( RandomUtils.random32(1, 5), exclude=("0,1,%d" % aStack.pointerIndex()), ) reference_stack_frame = [] for gpr_index in gpr_indices: gpr_val = self._loadRandomizedGprValue(gpr_index) reference_stack_frame.append([gpr_index, gpr_val]) self._mReferenceStackFrames.append(reference_stack_frame) aStack.newStackFrame(gpr_indices) self._assertStackFrameSize(aStack, len(reference_stack_frame)) elif operation == "freeStackFrame": reference_stack_frame = self._mReferenceStackFrames.pop() self._assertStackFrameSize(aStack, len(reference_stack_frame)) aStack.freeStackFrame() for (gpr_index, expected_gpr_val) in reference_stack_frame: exception_handlers_test_utils.assert_gpr_has_value( self, gpr_index, expected_gpr_val) elif operation == "arg": reference_stack_frame = self._mReferenceStackFrames[-1] arg_index = RandomUtils.random32( 0, (len(reference_stack_frame) - 1)) temp_gpr_index = self.getRandomGPR( exclude=("0,%d" % aStack.pointerIndex())) aStack.arg(temp_gpr_index, arg_index) exception_handlers_test_utils.assert_gpr_has_value( self, temp_gpr_index, reference_stack_frame[arg_index][1]) elif operation == "modifyArg": reference_stack_frame = self._mReferenceStackFrames[-1] arg_index = RandomUtils.random32( 0, (len(reference_stack_frame) - 1)) temp_gpr_index = self.getRandomGPR( exclude=("0,%d" % aStack.pointerIndex())) updated_arg_val = self._loadRandomizedGprValue(temp_gpr_index) reference_stack_frame[arg_index][1] = updated_arg_val aStack.modifyArg(temp_gpr_index, arg_index) else: self.error("Unexpected stack frame operation %s" % operation)
def generate(self, **kargs): for _ in range(50): pa_size_bits = RandomUtils.random32(1, 20) pa_size = 2**pa_size_bits pa_align_bits = RandomUtils.random32(1, pa_size_bits) pa_align = 2**pa_align_bits amo_mem_attr = self.choice( ("AMONone", "AMOSwap", "AMOLogical", "AMOArithmetic")) coherency_mem_attr = self.choice( ("CoherentL1", "CoherentL2", "CoherentL3", "Incoherent")) idempotency_mem_attr = self.choice( ("ReadIdempotent", "ReadNonIdempotent")) arch_mem_attributes = "%s,%s,%s" % ( amo_mem_attr, coherency_mem_attr, idempotency_mem_attr, ) impl_mem_attributes = self.choice( ("Debug", "CLINT", "PLIC", "GPIO")) # Constrain the PA to be in the valid VA range, so flat mapping doesn't fail pa_range = "0x0-0x7fffffffffff" if VirtualMemory.getPagingMode() == EPagingMode.Sv39: pa_range = "0x0-0x3fffffffff" start_addr = self.genPA( Size=pa_size, Align=pa_align, Type="D", MemAttrArch=arch_mem_attributes, MemAttrImpl=impl_mem_attributes, Range=pa_range, ) end_addr = start_addr + pa_size - 1 self._recordMemoryAttributes(arch_mem_attributes, start_addr, end_addr) self._recordMemoryAttributes(impl_mem_attributes, start_addr, end_addr) pa_for_va = RandomUtils.random64(start_addr, end_addr) va_size = RandomUtils.random32(1, (end_addr - pa_for_va + 1)) va_align_bits = RandomUtils.random32(0, (va_size.bit_length() - 1)) va_align = 2**va_align_bits pa_for_va = UtilityFunctions.getAlignedValue(pa_for_va, va_align) va_size = UtilityFunctions.getAlignedValue(va_size, va_align) self.genVAforPA( PA=pa_for_va, Size=va_size, Type="D", ) self._verifyMemoryAttributes()
def generate(self, **kargs): """ Initialize, read back and check the result for each architected register that is not reserved. Supported regs: x1-x31, S0-S31, D0-D31 Unsupported regs: fcsr Each entry in reg_list is a (reg_id string, mask bit pattern). The mask indicates which bits of reg are defined. after building the list of register id's, the test then intializes and reads each register and checks that the returned data matches. """ rv32 = self.getGlobalState("AppRegisterWidth") == 32 # Build the list of register ids reg_list = list() # generate GPR id's x1, x2 ... x31. x0 is not used. # mask=0xFFFFFFFFFFFFFFFF gpr_mask = 0xFFFFFFFF if rv32 else 0xFFFFFFFFFFFFFFFF for i in range(1, 32): reg_list.append(("x{}".format(i), gpr_mask)) # generate FPR id's D0, D1, ... D31. mask=0xFFFFFFFFFFFFFFFF for i in range(0, 32): reg_list.append(("D{}".format(i), 0xFFFFFFFFFFFFFFFF)) # generate FPR id's S0, S1, ... S31. mask=0x00000000FFFFFFFF for i in range(0, 32): reg_list.append(("S{}".format(i), 0x00000000FFFFFFFF)) # Do the initialize, read and compare test for each reg_id for (reg_id, reg_mask) in self.choicePermutated(reg_list): # skip initializing & checking registers that are already reserved if self.isRegisterReserved(reg_id, access="Write"): continue # skip initializing floating point registers that have already # been initialized under a different name if self._isFloatingPointRegisterInitialized(reg_id): continue initial_data = RandomUtils.random64() if reg_id[0] in ("x") and rv32: initial_data = RandomUtils.random32() self.initializeRegister(reg_id, initial_data) self._verifyInitialization(reg_id, reg_mask, initial_data)
def generate(self, **kargs): for i in range(2): instruction_group = RV_A_instructions for _ in range(RandomUtils.random32(1, 10)): the_instruction = self.pickWeighted(instruction_group) self.genInstruction(the_instruction) if RandomUtils.random32(0, 1) == 1: self.genInstruction('ECALL##RISCV') else: self.genInstruction('EBREAK##RISCV')
def _createStateC(self): state = State() self._mExpectedStateData = {} expected_sys_reg_state_data = [] fcsr_name = "fcsr" state.addSystemRegisterStateElementByField(fcsr_name, "FRM", 1) (fcsr_val, valid) = self.readRegister(fcsr_name) utils.assert_valid_register_value(self, fcsr_name, valid) fcsr_val = utils.combine_register_value_with_field_value( self, fcsr_name, fcsr_val, "FRM", 1) expected_fp_reg_state_data = [] for fp_reg_index in range(0, 32): fp_reg_val = RandomUtils.random64(0, 0x3FFFFFFFFFFFFFFF) state.addRegisterStateElement(("D%d" % fp_reg_index), (fp_reg_val, )) self._mExpectedStateData[ EStateElementType. FloatingPointRegister] = expected_fp_reg_state_data sstatus_name = "sstatus" fs_val = RandomUtils.random32(1, 3) state.addSystemRegisterStateElementByField(sstatus_name, "FS", fs_val) (sstatus_val, valid) = self.readRegister(sstatus_name) utils.assert_valid_register_value(self, sstatus_name, valid) sstatus_val = utils.combine_register_value_with_field_value( self, sstatus_name, sstatus_val, "FS", fs_val) # Adjust expected value of SD bit according to architecture rules (xs_val, valid) = self.readRegister(sstatus_name, field="XS") utils.assert_valid_register_value(self, sstatus_name, valid) (vs_val, valid) = self.readRegister(sstatus_name, field="VS") utils.assert_valid_register_value(self, sstatus_name, valid) if (fs_val == 3) or (xs_val == 3) or (vs_val == 3): sstatus_val = utils.combine_register_value_with_field_value( self, sstatus_name, sstatus_val, "SD", 1) else: sstatus_val = utils.combine_register_value_with_field_value( self, sstatus_name, sstatus_val, "SD", 0) expected_sys_reg_state_data.append((sstatus_name, sstatus_val)) self._mExpectedStateData[ EStateElementType.SystemRegister] = expected_sys_reg_state_data return state
def generate(self, **kargs): state = self._createState() target_addr_range = '%d-%d' % (self._mMemBlockStartAddr, self._mMemBlockEndAddr) instructions = ('LD##RISCV', 'SD##RISCV') for _ in range(RandomUtils.random32(2, 5)): for _ in range(RandomUtils.random32(50, 100)): self.genInstruction(self.choice(instructions), {'LSTarget': target_addr_range}) StateTransition.transitionToState(state) state_transition_test_utils.verifyState(self, self._mExpectedStateData)
def _loadRandomizedGprValue(self, aGprIndex): gpr_val = 0 if RandomUtils.random32(0, 1) == 0: gpr_name = 'x%d' % aGprIndex self.randomInitializeRegister(gpr_name) (gpr_val, valid) = self.readRegister(gpr_name) exception_handlers_test_utils.assertValidGprValue( self, aGprIndex, valid) else: load_gpr64_seq = LoadGPR64(self.genThread) gpr_val = RandomUtils.random64() load_gpr64_seq.load(aGprIndex, gpr_val) return gpr_val
def generate(self, **kargs): if self.getThreadGroupId() == 0: # Thread Group 0 generates random integer data processing # instructions for _ in range(RandomUtils.random32(50, 100)): instr = ALU_Int64_map.pick(self.genThread) self.genInstruction(instr) elif self.getThreadGroupId() == 1: # Thread Group 1 generates random integer load/store instructions for _ in range(RandomUtils.random32(50, 100)): instr = LDST_Int_map.pick(self.genThread) # The NoPreamble flag avoids generating instructions to load a # value into the base register prior to generating the load or # store instruction self.genInstruction(instr, {"NoPreamble": 1}) elif self.getThreadGroupId() == 2: # Thread Group 2 randomly selects from a large collection of # instructions for _ in range(RandomUtils.random32(50, 100)): instr = RV_G_map.pick(self.genThread) self.genInstruction(instr) else: # The remaining thread groups generate load/store instructions # targeting a shared memory location. A thread locking context # permits only one thread at a time to execute until the executing # thread exits the context. This ensures only one thread generates # the shared physical address and the remaining threads use it. shared_phys_addr = 0 shared_phys_addr_name = "Shared PA" with self.threadLockingContext(): if not self.hasSharedThreadObject(shared_phys_addr_name): shared_phys_addr = self.genPA(Size=8, Align=8, Type="D", Shared=1) self.setSharedThreadObject(shared_phys_addr_name, shared_phys_addr) else: shared_phys_addr = self.getSharedThreadObject( shared_phys_addr_name) target_addr = self.genVAforPA(Size=8, Align=8, Type="D", PA=shared_phys_addr) for _ in range(RandomUtils.random32(10, 20)): instr = LDST_Int_map.pick(self.genThread) self.genInstruction(instr, {"LSTarget": target_addr})
def _testExclusiveStoreLoad(self, aTargetAddr): src_reg_index = self.getRandomGPR(exclude="0") self.reserveRegister("x%d" % src_reg_index) if self.getGlobalState("AppRegisterWidth") == 64: load_gpr64_seq = LoadGPR64(self.genThread) test_val = RandomUtils.random64() load_gpr64_seq.load(src_reg_index, test_val) instr = "SD##RISCV" else: load_gpr32_seq = LoadGPR64(self.genThread) test_val = RandomUtils.random32() load_gpr32_seq.load(src_reg_index, test_val) instr = "SW##RISCV" self.genInstruction( instr, {"rs2": src_reg_index, "LSTarget": aTargetAddr} ) self.unreserveRegister("x%d" % src_reg_index) if self.getGlobalState("AppRegisterWidth") == 32: instr_map = RV32_G_map - BranchJump_map else: instr_map = RV_G_map - BranchJump_map for _ in range(RandomUtils.random32(5, 10)): instr = instr_map.pick(self.genThread) self.genInstruction(instr) if self.getGlobalState("AppRegisterWidth") == 32: instr = "LW##RISCV" else: instr = "LD##RISCV" instr_id = self.genInstruction(instr, {"LSTarget": aTargetAddr}) instr_record = self.queryInstructionRecord(instr_id) dest_reg_index = instr_record["Dests"]["rd"] if dest_reg_index != 0: dest_reg_name = "x%d" % dest_reg_index (dest_reg_val, valid) = self.readRegister(dest_reg_name) self._assertValidRegisterValue(dest_reg_name, valid) gen_mode = self.getPEstate("GenMode") no_iss = gen_mode & 0x1 if (no_iss != 1) and (dest_reg_val != test_val): self.error( "Unexpected destination register value; Expected=0x%x, " "Actual=0x%x" % (test_val, dest_reg_val) )
def _generateRegisterFieldValues(self): max_vsew_val = round(math.log2(self._mElen // 8)) self._mVsew = RandomUtils.random32(0, max_vsew_val) self._mVlmul = self.choice(self._getVlmulChoices()) self.mVtype = ((self._mVlmul & 0x4) << 3) | (self._mVsew << 2) | ( self._mVlmul & 0x3) vlmax = self._calculateVlmax() if RandomUtils.random32(0, 1) == 1: self.mAvl = RandomUtils.random32(0, vlmax) self._mVl = self.mAvl else: self.mAvl = RandomUtils.random32(aMin=(2 * vlmax)) self._mVl = vlmax
def addRandomVectorRegisterStateElements(aSequence, aState, aStateElemCount, aPriorityMin=1, aPriorityMax=100): expected_vec_reg_state_data = [] vec_reg_indices = aSequence.sample(range(0, 32), aStateElemCount) for vec_reg_index in vec_reg_indices: reg_val_count = aSequence.getLimitValue('MaxPhysicalVectorLen') // 64 vec_reg_values = [] for _ in range(reg_val_count): vec_reg_values.append(RandomUtils.random64()) vec_reg_name = 'v%d' % vec_reg_index aState.addRegisterStateElement(vec_reg_name, vec_reg_values, aPriority=RandomUtils.random32(aPriorityMin, aPriorityMax)) expected_vec_reg_state_data.append((vec_reg_name, vec_reg_values)) return expected_vec_reg_state_data
def _createState(self): state = State() self._mExpectedStateData[ EStateElementType. VectorRegister] = state_transition_test_utils.addRandomVectorRegisterStateElements( self, state, RandomUtils.random32(0, 15)) return state
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
def _createState(self): state = State() # The priorities are set in such a way as to enable floating point before loading the # floating point registers expected_sys_reg_state_data = [] sys_reg_name = 'misa' (sys_reg_val, valid) = self.readRegister(sys_reg_name) state_transition_test_utils.assertValidRegisterValue( self, sys_reg_name, valid) sys_reg_val |= 0x0000028 state.addRegisterStateElement(sys_reg_name, (sys_reg_val, ), aPriority=1) expected_sys_reg_state_data.append((sys_reg_name, sys_reg_val)) self._mExpectedStateData[ EStateElementType.SystemRegister] = expected_sys_reg_state_data self._mExpectedStateData[ EStateElementType. FloatingPointRegister] = state_transition_test_utils.addRandomFloatingPointRegisterStateElements( self, state, RandomUtils.random32(0, 10), aPriorityMin=2, aPriorityMax=4) return state
def generate(self, **kargs): for _ in range(RandomUtils.random32(250, 300)): if self.getGlobalState("AppRegisterWidth") == 32: instr = RV32_G_map.pick(self.genThread) else: instr = RV_G_map.pick(self.genThread) self.genInstruction(instr)
def pickWeighted(self, weighted_dict): from base.ItemMap import ItemMap from base.Macro import Macro total_weight = 0 for item, weight in weighted_dict.items(): total_weight += weight if total_weight <= 0: raise TestException("Sum of all weights in weighted-dict incorrect %d" % total_weight) picked_value = RandomUtils.random64(0, total_weight - 1); # print ("picked value %d, total weight %d" % (picked_value, total_weight)) for item, weight in sorted(weighted_dict.items()): if picked_value < weight: # found the picked item (instruction) if isinstance(item, str): return item elif isinstance(item, ItemMap): return item.pick(self) elif isinstance(item, Macro): return item else: raise TestException("Picked unsupported object.") picked_value -= weight else: Log.fail("Error picking item from weighted dict")
def _createState(self): state = State() self._mExpectedStateData[ EStateElementType. Memory] = state_transition_test_utils.add_random_memory_state_elements( self, state, RandomUtils.random32(0, 5)) return state