1*** Variables *** 2${MEMORY_START} 0x80000000 3${PLATFORM} SEPARATOR=\n 4... dram: Memory.MappedMemory @ sysbus ${MEMORY_START} { 5... ${SPACE*4}size: 0x80000000 6... } 7... mmio: Memory.ArrayMemory @ sysbus 0x100000000 { 8... ${SPACE*4}size: 0x10000 9... } 10... 11... cpu: CPU.RiscV64 @ sysbus { 12... ${SPACE*4}cpuType: "rv64gc_zicsr_zifencei"; 13... ${SPACE*4}hartId: 1; 14... ${SPACE*4}privilegedArchitecture: PrivilegedArchitecture.Priv1_10; 15... ${SPACE*4}timeProvider: empty; 16... ${SPACE*4}CyclesPerInstruction: 8; 17... ${SPACE*4}allowUnalignedAccesses: true 18... } 19${PAGE_SPANNING_ADDRESS} 0x0000000080000fff # Assuming page size is 4 KiB 20${MMIO_ADDRESS} 0x0000000100001000 21${MEMORY_VALUE} 0xffffffff80000000 22${INCREMENT_BY_X} 0xfffffffffffff800 23${INCREMENT_BY_Y} 0xffffffff80000000 24${EXPECTED_SUM_X_W} 0x000000007ffff800 25${EXPECTED_SUM_Y_W} 0x00000000fffff800 26${EXPECTED_SUM_X_D} 0xffffffff7ffff800 27${EXPECTED_SUM_Y_D} 0xffffffff7ffff000 28 29# Registers used 30${a0} 10 31${a1} 11 32${a2} 12 33 34*** Keywords *** 35Create Machine 36 Execute Command mach create 37 Execute Command machine LoadPlatformDescriptionFromString """${PLATFORM}""" 38 Execute Command cpu ExecutionMode SingleStep 39 Execute Command cpu PC 0x80000000 40 41Amoadd.w Should Increment Memory Location ${variable_address} 42 Create Machine 43 44 # Place value in memory. 45 Execute Command sysbus WriteDoubleWord ${variable_address} ${MEMORY_VALUE} 46 47 # The assembly instructions to execute in this test. 48 ${ASSEMBLY_AMOADD_W}= catenate SEPARATOR= 49 ... amoadd.w a2, a1, (a0); 50 ... amoadd.w a2, a1, (a0); 51 52 # Place machine code at PC. 53 Execute Command cpu AssembleBlock 0x80000000 "${ASSEMBLY_AMOADD_W}" 54 55 Execute Command cpu SetRegister ${a0} ${variable_address} 56 Execute Command cpu SetRegister ${a1} ${INCREMENT_BY_X} 57 58 # Perform amoadd to atomically increment memory location 59 Execute Command cpu Step 60 61 # After amoadd, rd register should have the original memory value (before the add)... 62 Register Should Be Equal ${a2} ${MEMORY_VALUE} cpuName=cpu 63 # and a1 should remain unchanged 64 Register Should Be Equal ${a1} ${INCREMENT_BY_X} cpuName=cpu 65 66 # Now value in memory should have been incremented. 67 ${res}= Execute Command sysbus ReadDoubleWord ${variable_address} 68 Should Be Equal As Integers ${res} ${EXPECTED_SUM_X_W} "first amoadd: Memory location should now contain ${EXPECTED_SUM_X_W}" 69 70 # Now, instead, increment by y. 71 Execute Command cpu SetRegister ${a1} ${INCREMENT_BY_Y} 72 73 # Perform amoadd again 74 Execute Command cpu Step 75 76 # After second amoadd, rd register should have the sum from the previous amoadd 77 Register Should Be Equal ${a2} ${EXPECTED_SUM_X_W} cpuName=cpu 78 79 # Now value in memory should have been incremented. 80 ${res}= Execute Command sysbus ReadDoubleWord ${variable_address} 81 Should Be Equal As Integers ${res} ${EXPECTED_SUM_Y_W} "second amoadd: Memory location should now contain ${EXPECTED_SUM_Y_W}" 82 83Amoadd.d Should Increment Memory Location ${variable_address} 84 Create Machine 85 86 # Place value in memory. 87 Execute Command sysbus WriteQuadWord ${variable_address} ${MEMORY_VALUE} 88 89 # The assembly instructions to execute in this test. 90 ${ASSEMBLY_AMOADD_D}= catenate SEPARATOR= 91 ... amoadd.d a2, a1, (a0); 92 ... amoadd.d a2, a1, (a0); 93 94 # Place machine code at PC. 95 Execute Command cpu AssembleBlock 0x80000000 "${ASSEMBLY_AMOADD_D}" 96 97 Execute Command cpu SetRegister ${a0} ${variable_address} 98 Execute Command cpu SetRegister ${a1} ${INCREMENT_BY_X} 99 100 # Perform amoadd to atomically increment memory location 101 Execute Command cpu Step 102 103 # After amoadd, rd register should have the original memory value (before the add)... 104 Register Should Be Equal ${a2} ${MEMORY_VALUE} cpuName=cpu 105 # and a1 should remain unchanged 106 Register Should Be Equal ${a1} ${INCREMENT_BY_X} cpuName=cpu 107 108 # Now value in memory should have been incremented. 109 ${res}= Execute Command sysbus ReadQuadWord ${variable_address} 110 Should Be Equal As Integers ${res} ${EXPECTED_SUM_X_D} "first amoadd: Memory location should now contain ${EXPECTED_SUM_X_D}" 111 112 # Load INCREMENT_BY_X into a1 again 113 Execute Command cpu SetRegister ${a1} ${INCREMENT_BY_X} 114 115 # Perform amoadd again 116 Execute Command cpu Step 117 118 # After second amoadd, rd register should have the sum from the previous amoadd 119 Register Should Be Equal ${a2} ${EXPECTED_SUM_X_D} cpuName=cpu 120 121 # Now value in memory should have been incremented. 122 ${res}= Execute Command sysbus ReadQuadWord ${variable_address} 123 Should Be Equal As Integers ${res} ${EXPECTED_SUM_Y_D} "second amoadd: Memory location should now contain ${EXPECTED_SUM_Y_D}" 124 125*** Test Cases *** 126Amoadd.w Should Increment Single-Page Memory Location 127 Amoadd.w Should Increment Memory Location 0x80000100 128 129Amoadd.d Should Increment Single-Page Memory Location 130 Amoadd.d Should Increment Memory Location 0x80000100 131 132Amoadd.w Should Increment Page-Spanning Memory Location 133 Amoadd.w Should Increment Memory Location ${PAGE_SPANNING_ADDRESS} 134 135Amoadd.d Should Increment Page-Spanning Memory Location 136 Amoadd.d Should Increment Memory Location ${PAGE_SPANNING_ADDRESS} 137 138Amoadd.d Should Increment MMIO Memory Location 139 Amoadd.d Should Increment Memory Location ${MMIO_ADDRESS} 140 141Amoadd.w Should Increment MMIO Memory Location 142 Amoadd.w Should Increment Memory Location ${MMIO_ADDRESS} 143