More SMP tests (barrier via AMO and LRSC)

This commit is contained in:
Dolu1990 2020-04-16 15:23:25 +02:00
parent fd52f9ba50
commit d88d04dbc4
4 changed files with 312 additions and 137 deletions

View File

@ -10,6 +10,8 @@ import vexriscv.ip.{DataCacheAck, DataCacheConfig, DataCacheMemBus, InstructionC
import vexriscv.plugin.{BranchPlugin, CsrPlugin, CsrPluginConfig, DBusCachedPlugin, DBusSimplePlugin, DebugPlugin, DecoderSimplePlugin, FullBarrelShifterPlugin, HazardSimplePlugin, IBusCachedPlugin, IBusSimplePlugin, IntAluPlugin, MmuPlugin, MmuPortConfig, MulDivIterativePlugin, MulPlugin, RegFilePlugin, STATIC, SrcPlugin, YamlPlugin}
import vexriscv.{VexRiscv, VexRiscvConfig, plugin}
import scala.collection.mutable
case class VexRiscvSmpClusterParameter( cpuConfigs : Seq[VexRiscvConfig])
@ -27,7 +29,8 @@ case class VexRiscvSmpCluster(p : VexRiscvSmpClusterParameter,
val io = new Bundle {
val dMem = master(Bmb(dMemParameter))
val iMem = master(Bmb(iMemParameter))
// val iMem = master(Bmb(iMemParameter))
val iMems = Vec(master(Bmb(iMemParameter)), p.cpuConfigs.size)
val timerInterrupts = in Bits(p.cpuConfigs.size bits)
val externalInterrupts = in Bits(p.cpuConfigs.size bits)
val externalSupervisorInterrupts = in Bits(p.cpuConfigs.size bits)
@ -87,18 +90,19 @@ case class VexRiscvSmpCluster(p : VexRiscvSmpClusterParameter,
io.dMem << invalidateMonitor.io.output
val iBusArbiter = BmbArbiter(
p = iBusArbiterParameter,
portCount = cpus.size,
pendingRspMax = 64,
lowerFirstPriority = false,
inputsWithInv = cpus.map(_ => true),
inputsWithSync = cpus.map(_ => true),
pendingInvMax = 16
)
(iBusArbiter.io.inputs, cpus).zipped.foreach(_ << _.iBus)
io.iMem << iBusArbiter.io.output
// val iBusArbiter = BmbArbiter(
// p = iBusArbiterParameter,
// portCount = cpus.size,
// pendingRspMax = 64,
// lowerFirstPriority = false,
// inputsWithInv = cpus.map(_ => true),
// inputsWithSync = cpus.map(_ => true),
// pendingInvMax = 16
// )
//
// (iBusArbiter.io.inputs, cpus).zipped.foreach(_ << _.iBus)
// io.iMem << iBusArbiter.io.output
(io.iMems, cpus).zipped.foreach(_ << _.iBus)
}
@ -274,6 +278,14 @@ object VexRiscvSmpClusterGen {
}
object SmpTest{
val REPORT_OFFSET = 0xF8000000
val REPORT_THREAD_ID = 0x00
val REPORT_THREAD_COUNT = 0x04
val REPORT_END = 0x08
val REPORT_BARRIER_START = 0x0C
val REPORT_BARRIER_END = 0x10
}
object VexRiscvSmpClusterTest extends App{
import spinal.core.sim._
@ -282,21 +294,57 @@ object VexRiscvSmpClusterTest extends App{
simConfig.allOptimisation
simConfig.addSimulatorFlag("--threads 1")
simConfig.compile(VexRiscvSmpClusterGen.vexRiscvCluster()).doSim(seed = 42){dut =>
simConfig.compile(VexRiscvSmpClusterGen.vexRiscvCluster()).doSimUntilVoid(seed = 42){dut =>
SimTimeout(10000*10)
dut.clockDomain.forkSimSpeedPrinter(1.0)
dut.clockDomain.forkStimulus(10)
dut.debugClockDomain.forkStimulus(10)
val hartCount = dut.cpus.size
JtagTcp(dut.io.jtag, 100)
val ram = new BmbMemoryAgent(0x100000000l)
ram.addPort(dut.io.iMem,0,dut.clockDomain,true)
ram.addPort(dut.io.dMem,0,dut.clockDomain,true)
val withStall = false
val cpuEnd = Array.fill(dut.p.cpuConfigs.size)(false)
val barriers = mutable.HashMap[Int, Int]()
val ram = new BmbMemoryAgent(0x100000000l){
var writeData = 0
override def setByte(address: Long, value: Byte): Unit = {
if((address & 0xF0000000l) != 0xF0000000l) return super.setByte(address, value)
val byteId = address & 3
val mask = 0xFF << (byteId*8)
writeData = (writeData & ~mask) | ((value.toInt << (byteId*8)) & mask)
if(byteId != 3) return
val offset = (address & ~0xF0000000l)-3
println(s"W[0x${offset.toHexString}] = $writeData")
offset match {
case _ if offset >= 0x8000000 && offset < 0x9000000 => {
val hart = ((offset & 0xFF0000) >> 16).toInt
val code = (offset & 0x00FFFF).toInt
val data = writeData
import SmpTest._
code match {
case REPORT_THREAD_ID => assert(data == hart)
case REPORT_THREAD_COUNT => assert(data == hartCount)
case REPORT_END => assert(data == 0); assert(cpuEnd(hart) == false); cpuEnd(hart) = true; if(!cpuEnd.exists(_ == false)) simSuccess()
case REPORT_BARRIER_START => {
val counter = barriers.getOrElse(data, 0)
assert(counter < hartCount)
barriers(data) = counter + 1
}
case REPORT_BARRIER_END => {
val counter = barriers.getOrElse(data, 0)
assert(counter == hartCount)
}
}
}
}
}
}
dut.io.iMems.foreach(ram.addPort(_,0,dut.clockDomain,true, withStall)) //Moarr powaaaaa
// ram.addPort(dut.io.iMem,0,dut.clockDomain,true, withStall)
ram.addPort(dut.io.dMem,0,dut.clockDomain,true, withStall)
ram.memory.loadBin(0x80000000l, "src/test/cpp/raw/smp/build/smp.bin")
sleep(10000*10)
simSuccess()
}
}

View File

@ -5,104 +5,171 @@ build/smp.elf: file format elf32-littleriscv
Disassembly of section .crt_section:
80000000 <_start>:
80000000: f1402a73 csrr s4,mhartid
80000004: 00000517 auipc a0,0x0
80000008: 07850513 addi a0,a0,120 # 8000007c <test1_data>
8000000c: 00000513 li a0,0
80000010: 00a52023 sw a0,0(a0)
80000000: f1402473 csrr s0,mhartid
80000004: f80002b7 lui t0,0xf8000
80000008: f1402373 csrr t1,mhartid
8000000c: 01031313 slli t1,t1,0x10
80000010: 006282b3 add t0,t0,t1
80000014: 0082a023 sw s0,0(t0) # f8000000 <barrier_lrsc_value+0x77fffe14>
80000014 <count_thread_start>:
80000014: 00100513 li a0,1
80000018: 00000597 auipc a1,0x0
8000001c: 05c58593 addi a1,a1,92 # 80000074 <thread_count>
80000020: 00a5a02f amoadd.w zero,a0,(a1)
80000018 <count_thread_start>:
80000018: 00100513 li a0,1
8000001c: 00000597 auipc a1,0x0
80000020: 1c458593 addi a1,a1,452 # 800001e0 <thread_count>
80000024: 00a5a02f amoadd.w zero,a0,(a1)
80000024 <count_thread_wait>:
80000024: 00000417 auipc s0,0x0
80000028: 05042403 lw s0,80(s0) # 80000074 <thread_count>
8000002c: 0c800513 li a0,200
80000030: 038000ef jal ra,80000068 <sleep>
80000034: 00000497 auipc s1,0x0
80000038: 0404a483 lw s1,64(s1) # 80000074 <thread_count>
8000003c: fe8494e3 bne s1,s0,80000024 <count_thread_wait>
80000040: 00000513 li a0,0
80000044: 00952023 sw s1,0(a0)
80000048: 0040006f j 8000004c <success>
80000028 <count_thread_wait>:
80000028: 00000417 auipc s0,0x0
8000002c: 1b842403 lw s0,440(s0) # 800001e0 <thread_count>
80000030: 0c800513 li a0,200
80000034: 1a0000ef jal ra,800001d4 <sleep>
80000038: 00000497 auipc s1,0x0
8000003c: 1a84a483 lw s1,424(s1) # 800001e0 <thread_count>
80000040: fe8494e3 bne s1,s0,80000028 <count_thread_wait>
80000044: f80002b7 lui t0,0xf8000
80000048: 00428293 addi t0,t0,4 # f8000004 <barrier_lrsc_value+0x77fffe18>
8000004c: f1402373 csrr t1,mhartid
80000050: 01031313 slli t1,t1,0x10
80000054: 006282b3 add t0,t0,t1
80000058: 0092a023 sw s1,0(t0)
8000004c <success>:
8000004c: 00800513 li a0,8
80000050: 00052023 sw zero,0(a0)
80000054: 0100006f j 80000064 <end>
8000005c <barrier_amo_test>:
8000005c: 00100513 li a0,1
80000060: 040000ef jal ra,800000a0 <barrier_amo>
80000064: 00200513 li a0,2
80000068: 038000ef jal ra,800000a0 <barrier_amo>
8000006c: 00300513 li a0,3
80000070: 030000ef jal ra,800000a0 <barrier_amo>
80000074: 00400513 li a0,4
80000078: 09c000ef jal ra,80000114 <barrier_lrsc>
8000007c: 00500513 li a0,5
80000080: 094000ef jal ra,80000114 <barrier_lrsc>
80000084: 00600513 li a0,6
80000088: 08c000ef jal ra,80000114 <barrier_lrsc>
8000008c: 00700513 li a0,7
80000090: 010000ef jal ra,800000a0 <barrier_amo>
80000094: 00800513 li a0,8
80000098: 07c000ef jal ra,80000114 <barrier_lrsc>
8000009c: 0f40006f j 80000190 <success>
80000058 <failure>:
80000058: 00c00513 li a0,12
8000005c: 00052023 sw zero,0(a0)
80000060: 0040006f j 80000064 <end>
800000a0 <barrier_amo>:
800000a0: f80002b7 lui t0,0xf8000
800000a4: 00c28293 addi t0,t0,12 # f800000c <barrier_lrsc_value+0x77fffe20>
800000a8: f1402373 csrr t1,mhartid
800000ac: 01031313 slli t1,t1,0x10
800000b0: 006282b3 add t0,t0,t1
800000b4: 00a2a023 sw a0,0(t0)
800000b8: 00000297 auipc t0,0x0
800000bc: 13028293 addi t0,t0,304 # 800001e8 <barrier_amo_value>
800000c0: 00100313 li t1,1
800000c4: 0062a02f amoadd.w zero,t1,(t0)
800000c8: 00000317 auipc t1,0x0
800000cc: 11832303 lw t1,280(t1) # 800001e0 <thread_count>
80000064 <end>:
80000064: 0000006f j 80000064 <end>
800000d0 <barrier_amo_wait>:
800000d0: 0002a383 lw t2,0(t0)
800000d4: fe639ee3 bne t2,t1,800000d0 <barrier_amo_wait>
800000d8: f80002b7 lui t0,0xf8000
800000dc: 01028293 addi t0,t0,16 # f8000010 <barrier_lrsc_value+0x77fffe24>
800000e0: f1402373 csrr t1,mhartid
800000e4: 01031313 slli t1,t1,0x10
800000e8: 006282b3 add t0,t0,t1
800000ec: 00a2a023 sw a0,0(t0)
80000068 <sleep>:
80000068: fff50513 addi a0,a0,-1
8000006c: fe051ee3 bnez a0,80000068 <sleep>
80000070: 00008067 ret
800000f0 <barrier_amo_reset>:
800000f0: f14022f3 csrr t0,mhartid
800000f4: 00029863 bnez t0,80000104 <barrier_amo_reset_wait>
800000f8: 00000297 auipc t0,0x0
800000fc: 0e02a823 sw zero,240(t0) # 800001e8 <barrier_amo_value>
80000100: 00008067 ret
80000074 <thread_count>:
80000074: 0000 unimp
80000104 <barrier_amo_reset_wait>:
80000104: 00000297 auipc t0,0x0
80000108: 0e42a283 lw t0,228(t0) # 800001e8 <barrier_amo_value>
8000010c: fe029ce3 bnez t0,80000104 <barrier_amo_reset_wait>
80000110: 00008067 ret
80000114 <barrier_lrsc>:
80000114: f80002b7 lui t0,0xf8000
80000118: 00c28293 addi t0,t0,12 # f800000c <barrier_lrsc_value+0x77fffe20>
8000011c: f1402373 csrr t1,mhartid
80000120: 01031313 slli t1,t1,0x10
80000124: 006282b3 add t0,t0,t1
80000128: 00a2a023 sw a0,0(t0)
8000012c: 00000297 auipc t0,0x0
80000130: 0c028293 addi t0,t0,192 # 800001ec <barrier_lrsc_value>
80000134 <barrier_lrsc_try>:
80000134: 1002a32f lr.w t1,(t0)
80000138: 00130313 addi t1,t1,1
8000013c: 1862a32f sc.w t1,t1,(t0)
80000140: fe031ae3 bnez t1,80000134 <barrier_lrsc_try>
80000144: 00000317 auipc t1,0x0
80000148: 09c32303 lw t1,156(t1) # 800001e0 <thread_count>
8000014c <barrier_lrsc_wait>:
8000014c: 0002a383 lw t2,0(t0)
80000150: fe639ee3 bne t2,t1,8000014c <barrier_lrsc_wait>
80000154: f80002b7 lui t0,0xf8000
80000158: 01028293 addi t0,t0,16 # f8000010 <barrier_lrsc_value+0x77fffe24>
8000015c: f1402373 csrr t1,mhartid
80000160: 01031313 slli t1,t1,0x10
80000164: 006282b3 add t0,t0,t1
80000168: 00a2a023 sw a0,0(t0)
8000016c <barrier_lrsc_reset>:
8000016c: f14022f3 csrr t0,mhartid
80000170: 00029863 bnez t0,80000180 <barrier_lrsc_reset_wait>
80000174: 00000297 auipc t0,0x0
80000178: 0602ac23 sw zero,120(t0) # 800001ec <barrier_lrsc_value>
8000017c: 00008067 ret
80000180 <barrier_lrsc_reset_wait>:
80000180: 00000297 auipc t0,0x0
80000184: 06c2a283 lw t0,108(t0) # 800001ec <barrier_lrsc_value>
80000188: fe029ce3 bnez t0,80000180 <barrier_lrsc_reset_wait>
8000018c: 00008067 ret
80000190 <success>:
80000190: 00000413 li s0,0
80000194: f80002b7 lui t0,0xf8000
80000198: 00828293 addi t0,t0,8 # f8000008 <barrier_lrsc_value+0x77fffe1c>
8000019c: f1402373 csrr t1,mhartid
800001a0: 01031313 slli t1,t1,0x10
800001a4: 006282b3 add t0,t0,t1
800001a8: 0082a023 sw s0,0(t0)
800001ac: 0240006f j 800001d0 <end>
800001b0 <failure>:
800001b0: 00100413 li s0,1
800001b4: f80002b7 lui t0,0xf8000
800001b8: 00828293 addi t0,t0,8 # f8000008 <barrier_lrsc_value+0x77fffe1c>
800001bc: f1402373 csrr t1,mhartid
800001c0: 01031313 slli t1,t1,0x10
800001c4: 006282b3 add t0,t0,t1
800001c8: 0082a023 sw s0,0(t0)
800001cc: 0040006f j 800001d0 <end>
800001d0 <end>:
800001d0: 0000006f j 800001d0 <end>
800001d4 <sleep>:
800001d4: fff50513 addi a0,a0,-1
800001d8: fe051ee3 bnez a0,800001d4 <sleep>
800001dc: 00008067 ret
800001e0 <thread_count>:
800001e0: 0000 unimp
...
80000078 <shared_memory_1>:
80000078: 0000 unimp
800001e4 <shared_memory_1>:
800001e4: 0000 unimp
...
8000007c <test1_data>:
8000007c: 0000000b 0xb
80000080 <test2_data>:
80000080: 0016 c.slli zero,0x5
800001e8 <barrier_amo_value>:
800001e8: 0000 unimp
...
80000084 <test3_data>:
80000084: 0049 c.nop 18
800001ec <barrier_lrsc_value>:
800001ec: 0000 unimp
...
80000088 <test4_data>:
80000088: 003a c.slli zero,0xe
...
8000008c <test5_data>:
8000008c: 0038 addi a4,sp,8
...
80000090 <test6_data>:
80000090: 0000004b fnmsub.s ft0,ft0,ft0,ft0,rne
80000094 <test7_data>:
80000094: 0038 addi a4,sp,8
...
80000098 <test8_data>:
80000098: 00000053 fadd.s ft0,ft0,ft0,rne
8000009c <test9_data>:
8000009c: 0021 c.nop 8
...
800000a0 <test10_data>:
800000a0: ffffffbf 0xffffffbf
800000a4 <test11_data>:
800000a4: ffa9 bnez a5,7ffffffe <_start-0x2>
800000a6: ffff 0xffff
800000a8 <test12_data>:
800000a8: ffc9 bnez a5,80000042 <count_thread_wait+0x1e>
800000aa: ffff 0xffff
800000ac <test13_data>:
800000ac: 0004 0x4
800000ae: ffff 0xffff
800000b0 <test14_data>:
800000b0: 0005 c.nop 1
800000b2: ffff 0xffff

Binary file not shown.

View File

@ -1,19 +1,20 @@
#define REPORT_OFFSET 0xF0000000
#define REPORT_THREAD_ID 0
#define REPORT_THREAD_COUNT 1
#define REPORT_SUCCESS 2
#define REPORT_FAILURE 3
#define REPORT_OFFSET 0xF8000000
#define REPORT_THREAD_ID 0x00
#define REPORT_THREAD_COUNT 0x04
#define REPORT_END 0x08
#define REPORT_BARRIER_START 0x0C
#define REPORT_BARRIER_END 0x10
#define report(reg, id) \
li a0, id*4; \
sw reg, 0(a0); \
li t0, REPORT_OFFSET+id; \
csrr t1, mhartid; \
slli t1, t1, 16; \
add t0, t0, t1; \
sw reg, 0(t0); \
_start:
#define HART_ID x20
csrr HART_ID, mhartid
la a0, test1_data
report(a0, REPORT_THREAD_ID)
csrr s0, mhartid
report(s0, REPORT_THREAD_ID)
count_thread_start:
@ -29,16 +30,88 @@ count_thread_wait:
call sleep
lw s1, thread_count
bne s1, s0, count_thread_wait
report(s1, REPORT_THREAD_ID)
report(s1, REPORT_THREAD_COUNT)
barrier_amo_test:
li a0, 1
call barrier_amo
li a0, 2
call barrier_amo
li a0, 3
call barrier_amo
li a0, 4
call barrier_lrsc
li a0, 5
call barrier_lrsc
li a0, 6
call barrier_lrsc
li a0, 7
call barrier_amo
li a0, 8
call barrier_lrsc
j success
barrier_amo:
report(a0, REPORT_BARRIER_START)
la t0, barrier_amo_value
li t1, 1
amoadd.w x0, t1, (t0)
lw t1, thread_count
barrier_amo_wait:
lw t2, (t0)
bne t2, t1, barrier_amo_wait
report(a0, REPORT_BARRIER_END)
barrier_amo_reset:
csrr t0, mhartid
bnez t0, barrier_amo_reset_wait
sw x0, barrier_amo_value, t0
ret
barrier_amo_reset_wait:
lw t0, barrier_amo_value
bnez t0, barrier_amo_reset_wait
ret
barrier_lrsc:
report(a0, REPORT_BARRIER_START)
la t0, barrier_lrsc_value
barrier_lrsc_try:
lr.w t1, (t0)
addi t1, t1, 1
sc.w t1, t1, (t0)
bnez t1, barrier_lrsc_try
lw t1, thread_count
barrier_lrsc_wait:
lw t2, (t0)
bne t2, t1, barrier_lrsc_wait
report(a0, REPORT_BARRIER_END)
barrier_lrsc_reset:
csrr t0, mhartid
bnez t0, barrier_lrsc_reset_wait
sw x0, barrier_lrsc_value, t0
ret
barrier_lrsc_reset_wait:
lw t0, barrier_lrsc_value
bnez t0, barrier_lrsc_reset_wait
ret
success:
report(x0, REPORT_SUCCESS)
li s0, 0
report(s0, REPORT_END)
j end
failure:
report(x0, REPORT_FAILURE)
li s0, 1
report(s0, REPORT_END)
j end
end:
@ -53,18 +126,5 @@ sleep:
thread_count: .word 0
shared_memory_1: .word 0
test1_data: .word 11
test2_data: .word 22
test3_data: .word 73
test4_data: .word 58
test5_data: .word 56
test6_data: .word 75
test7_data: .word 56
test8_data: .word 83
test9_data: .word 33
test10_data: .word -65
test11_data: .word -87
test12_data: .word -55
test13_data: .word 0xFFFF0004
test14_data: .word 0xFFFF0005
barrier_amo_value: .word 0
barrier_lrsc_value: .word 0