Add VexRiscvSmpCluster, seem to work on simple case
This commit is contained in:
parent
b9ceabf128
commit
73c21177e5
|
@ -0,0 +1,302 @@
|
||||||
|
package vexriscv.demo.smp
|
||||||
|
|
||||||
|
import spinal.core._
|
||||||
|
import spinal.lib._
|
||||||
|
import spinal.lib.bus.bmb.sim.BmbMemoryAgent
|
||||||
|
import spinal.lib.bus.bmb.{Bmb, BmbArbiter, BmbDecoder, BmbExclusiveMonitor, BmbInvalidateMonitor, BmbParameter}
|
||||||
|
import spinal.lib.com.jtag.Jtag
|
||||||
|
import spinal.lib.com.jtag.sim.JtagTcp
|
||||||
|
import vexriscv.ip.{DataCacheAck, DataCacheConfig, DataCacheMemBus, InstructionCacheConfig}
|
||||||
|
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}
|
||||||
|
|
||||||
|
|
||||||
|
case class VexRiscvSmpClusterParameter( cpuConfigs : Seq[VexRiscvConfig])
|
||||||
|
|
||||||
|
case class VexRiscvSmpCluster(p : VexRiscvSmpClusterParameter,
|
||||||
|
debugClockDomain : ClockDomain) extends Component{
|
||||||
|
val dBusParameter = p.cpuConfigs.head.plugins.find(_.isInstanceOf[DBusCachedPlugin]).get.asInstanceOf[DBusCachedPlugin].config.getBmbParameter()
|
||||||
|
val dBusArbiterParameter = dBusParameter.copy(sourceWidth = log2Up(p.cpuConfigs.size))
|
||||||
|
val exclusiveMonitorParameter = dBusArbiterParameter
|
||||||
|
val invalidateMonitorParameter = BmbExclusiveMonitor.outputParameter(exclusiveMonitorParameter)
|
||||||
|
val dMemParameter = BmbInvalidateMonitor.outputParameter(invalidateMonitorParameter)
|
||||||
|
|
||||||
|
val iBusParameter = p.cpuConfigs.head.plugins.find(_.isInstanceOf[IBusCachedPlugin]).get.asInstanceOf[IBusCachedPlugin].config.getBmbParameter()
|
||||||
|
val iBusArbiterParameter = iBusParameter.copy(sourceWidth = log2Up(p.cpuConfigs.size))
|
||||||
|
val iMemParameter = iBusArbiterParameter
|
||||||
|
|
||||||
|
val io = new Bundle {
|
||||||
|
val dMem = master(Bmb(dMemParameter))
|
||||||
|
val iMem = master(Bmb(iMemParameter))
|
||||||
|
val timerInterrupts = in Bits(p.cpuConfigs.size bits)
|
||||||
|
val externalInterrupts = in Bits(p.cpuConfigs.size bits)
|
||||||
|
val externalSupervisorInterrupts = in Bits(p.cpuConfigs.size bits)
|
||||||
|
val jtag = slave(Jtag())
|
||||||
|
val debugReset = out Bool()
|
||||||
|
}
|
||||||
|
|
||||||
|
val cpus = for((cpuConfig, cpuId) <- p.cpuConfigs.zipWithIndex) yield new Area{
|
||||||
|
var iBus : Bmb = null
|
||||||
|
var dBus : Bmb = null
|
||||||
|
cpuConfig.plugins.foreach {
|
||||||
|
case plugin: DebugPlugin => debugClockDomain{
|
||||||
|
plugin.debugClockDomain = debugClockDomain
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
val core = new VexRiscv(cpuConfig)
|
||||||
|
core.plugins.foreach {
|
||||||
|
case plugin: IBusCachedPlugin => iBus = plugin.iBus.toBmb()
|
||||||
|
case plugin: DBusCachedPlugin => dBus = plugin.dBus.toBmb()
|
||||||
|
case plugin: CsrPlugin => {
|
||||||
|
plugin.externalInterrupt := io.externalInterrupts(cpuId)
|
||||||
|
plugin.timerInterrupt := io.timerInterrupts(cpuId)
|
||||||
|
if (plugin.config.supervisorGen) plugin.externalInterruptS := io.externalSupervisorInterrupts(cpuId)
|
||||||
|
}
|
||||||
|
case plugin: DebugPlugin => debugClockDomain{
|
||||||
|
io.debugReset := RegNext(plugin.io.resetOut)
|
||||||
|
io.jtag <> plugin.io.bus.fromJtag()
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val dBusArbiter = BmbArbiter(
|
||||||
|
p = dBusArbiterParameter,
|
||||||
|
portCount = cpus.size,
|
||||||
|
pendingRspMax = 64,
|
||||||
|
lowerFirstPriority = false,
|
||||||
|
inputsWithInv = cpus.map(_ => true),
|
||||||
|
inputsWithSync = cpus.map(_ => true),
|
||||||
|
pendingInvMax = 16
|
||||||
|
)
|
||||||
|
|
||||||
|
(dBusArbiter.io.inputs, cpus).zipped.foreach(_ << _.dBus)
|
||||||
|
|
||||||
|
val exclusiveMonitor = BmbExclusiveMonitor(
|
||||||
|
inputParameter = exclusiveMonitorParameter,
|
||||||
|
pendingWriteMax = 64
|
||||||
|
)
|
||||||
|
exclusiveMonitor.io.input << dBusArbiter.io.output
|
||||||
|
|
||||||
|
val invalidateMonitor = BmbInvalidateMonitor(
|
||||||
|
inputParameter = invalidateMonitorParameter,
|
||||||
|
pendingInvMax = 16
|
||||||
|
)
|
||||||
|
invalidateMonitor.io.input << exclusiveMonitor.io.output
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
object VexRiscvSmpClusterGen {
|
||||||
|
def vexRiscvConfig(id : Int) = {
|
||||||
|
val config = VexRiscvConfig(
|
||||||
|
plugins = List(
|
||||||
|
new MmuPlugin(
|
||||||
|
ioRange = x => x(31 downto 28) === 0xF
|
||||||
|
),
|
||||||
|
//Uncomment the whole IBusSimplePlugin and comment IBusCachedPlugin if you want uncached iBus config
|
||||||
|
// new IBusSimplePlugin(
|
||||||
|
// resetVector = 0x80000000l,
|
||||||
|
// cmdForkOnSecondStage = false,
|
||||||
|
// cmdForkPersistence = false,
|
||||||
|
// prediction = DYNAMIC_TARGET,
|
||||||
|
// historyRamSizeLog2 = 10,
|
||||||
|
// catchAccessFault = true,
|
||||||
|
// compressedGen = true,
|
||||||
|
// busLatencyMin = 1,
|
||||||
|
// injectorStage = true,
|
||||||
|
// memoryTranslatorPortConfig = withMmu generate MmuPortConfig(
|
||||||
|
// portTlbSize = 4
|
||||||
|
// )
|
||||||
|
// ),
|
||||||
|
|
||||||
|
//Uncomment the whole IBusCachedPlugin and comment IBusSimplePlugin if you want cached iBus config
|
||||||
|
new IBusCachedPlugin(
|
||||||
|
resetVector = 0x80000000l,
|
||||||
|
compressedGen = false,
|
||||||
|
prediction = STATIC,
|
||||||
|
injectorStage = false,
|
||||||
|
config = InstructionCacheConfig(
|
||||||
|
cacheSize = 4096*1,
|
||||||
|
bytePerLine = 32,
|
||||||
|
wayCount = 1,
|
||||||
|
addressWidth = 32,
|
||||||
|
cpuDataWidth = 32,
|
||||||
|
memDataWidth = 32,
|
||||||
|
catchIllegalAccess = true,
|
||||||
|
catchAccessFault = true,
|
||||||
|
asyncTagMemory = false,
|
||||||
|
twoCycleRam = false,
|
||||||
|
twoCycleCache = true
|
||||||
|
// )
|
||||||
|
),
|
||||||
|
memoryTranslatorPortConfig = MmuPortConfig(
|
||||||
|
portTlbSize = 4
|
||||||
|
)
|
||||||
|
),
|
||||||
|
// ).newTightlyCoupledPort(TightlyCoupledPortParameter("iBusTc", a => a(30 downto 28) === 0x0 && a(5))),
|
||||||
|
// new DBusSimplePlugin(
|
||||||
|
// catchAddressMisaligned = true,
|
||||||
|
// catchAccessFault = true,
|
||||||
|
// earlyInjection = false,
|
||||||
|
// withLrSc = true,
|
||||||
|
// memoryTranslatorPortConfig = withMmu generate MmuPortConfig(
|
||||||
|
// portTlbSize = 4
|
||||||
|
// )
|
||||||
|
// ),
|
||||||
|
new DBusCachedPlugin(
|
||||||
|
dBusCmdMasterPipe = true,
|
||||||
|
dBusCmdSlavePipe = true,
|
||||||
|
dBusRspSlavePipe = true,
|
||||||
|
config = new DataCacheConfig(
|
||||||
|
cacheSize = 4096*1,
|
||||||
|
bytePerLine = 32,
|
||||||
|
wayCount = 1,
|
||||||
|
addressWidth = 32,
|
||||||
|
cpuDataWidth = 32,
|
||||||
|
memDataWidth = 32,
|
||||||
|
catchAccessError = true,
|
||||||
|
catchIllegal = true,
|
||||||
|
catchUnaligned = true,
|
||||||
|
withLrSc = true,
|
||||||
|
withAmo = true,
|
||||||
|
withExclusive = true,
|
||||||
|
withInvalidate = true
|
||||||
|
// )
|
||||||
|
),
|
||||||
|
memoryTranslatorPortConfig = MmuPortConfig(
|
||||||
|
portTlbSize = 4
|
||||||
|
)
|
||||||
|
),
|
||||||
|
|
||||||
|
// new MemoryTranslatorPlugin(
|
||||||
|
// tlbSize = 32,
|
||||||
|
// virtualRange = _(31 downto 28) === 0xC,
|
||||||
|
// ioRange = _(31 downto 28) === 0xF
|
||||||
|
// ),
|
||||||
|
|
||||||
|
new DecoderSimplePlugin(
|
||||||
|
catchIllegalInstruction = true
|
||||||
|
),
|
||||||
|
new RegFilePlugin(
|
||||||
|
regFileReadyKind = plugin.SYNC,
|
||||||
|
zeroBoot = true
|
||||||
|
),
|
||||||
|
new IntAluPlugin,
|
||||||
|
new SrcPlugin(
|
||||||
|
separatedAddSub = false
|
||||||
|
),
|
||||||
|
new FullBarrelShifterPlugin(earlyInjection = false),
|
||||||
|
// new LightShifterPlugin,
|
||||||
|
new HazardSimplePlugin(
|
||||||
|
bypassExecute = true,
|
||||||
|
bypassMemory = true,
|
||||||
|
bypassWriteBack = true,
|
||||||
|
bypassWriteBackBuffer = true,
|
||||||
|
pessimisticUseSrc = false,
|
||||||
|
pessimisticWriteRegFile = false,
|
||||||
|
pessimisticAddressMatch = false
|
||||||
|
),
|
||||||
|
// new HazardSimplePlugin(false, true, false, true),
|
||||||
|
// new HazardSimplePlugin(false, false, false, false),
|
||||||
|
new MulPlugin,
|
||||||
|
new MulDivIterativePlugin(
|
||||||
|
genMul = false,
|
||||||
|
genDiv = true,
|
||||||
|
mulUnrollFactor = 32,
|
||||||
|
divUnrollFactor = 1
|
||||||
|
),
|
||||||
|
// new DivPlugin,
|
||||||
|
new CsrPlugin(CsrPluginConfig.all2(0x80000020l).copy(ebreakGen = false, mhartid = id)),
|
||||||
|
// new CsrPlugin(//CsrPluginConfig.all2(0x80000020l).copy(ebreakGen = true)/*
|
||||||
|
// CsrPluginConfig(
|
||||||
|
// catchIllegalAccess = false,
|
||||||
|
// mvendorid = null,
|
||||||
|
// marchid = null,
|
||||||
|
// mimpid = null,
|
||||||
|
// mhartid = null,
|
||||||
|
// misaExtensionsInit = 0,
|
||||||
|
// misaAccess = CsrAccess.READ_ONLY,
|
||||||
|
// mtvecAccess = CsrAccess.WRITE_ONLY,
|
||||||
|
// mtvecInit = 0x80000020l,
|
||||||
|
// mepcAccess = CsrAccess.READ_WRITE,
|
||||||
|
// mscratchGen = true,
|
||||||
|
// mcauseAccess = CsrAccess.READ_ONLY,
|
||||||
|
// mbadaddrAccess = CsrAccess.READ_ONLY,
|
||||||
|
// mcycleAccess = CsrAccess.NONE,
|
||||||
|
// minstretAccess = CsrAccess.NONE,
|
||||||
|
// ecallGen = true,
|
||||||
|
// ebreakGen = true,
|
||||||
|
// wfiGenAsWait = false,
|
||||||
|
// wfiGenAsNop = true,
|
||||||
|
// ucycleAccess = CsrAccess.NONE
|
||||||
|
// )),
|
||||||
|
new BranchPlugin(
|
||||||
|
earlyBranch = false,
|
||||||
|
catchAddressMisaligned = true,
|
||||||
|
fenceiGenAsAJump = false
|
||||||
|
),
|
||||||
|
new YamlPlugin(s"cpu$id.yaml")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if(id == 0) config.plugins += new DebugPlugin(null)
|
||||||
|
config
|
||||||
|
}
|
||||||
|
def vexRiscvCluster() = VexRiscvSmpCluster(
|
||||||
|
debugClockDomain = ClockDomain.current.copy(reset = Bool().setName("debugResetIn")),
|
||||||
|
p = VexRiscvSmpClusterParameter(
|
||||||
|
cpuConfigs = List.tabulate(4) {
|
||||||
|
vexRiscvConfig(_)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
def main(args: Array[String]): Unit = {
|
||||||
|
SpinalVerilog {
|
||||||
|
vexRiscvCluster()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object VexRiscvSmpClusterTest extends App{
|
||||||
|
import spinal.core.sim._
|
||||||
|
|
||||||
|
val simConfig = SimConfig
|
||||||
|
simConfig.withWave
|
||||||
|
simConfig.allOptimisation
|
||||||
|
simConfig.addSimulatorFlag("--threads 1")
|
||||||
|
|
||||||
|
simConfig.compile(VexRiscvSmpClusterGen.vexRiscvCluster()).doSim(seed = 42){dut =>
|
||||||
|
dut.clockDomain.forkSimSpeedPrinter(1.0)
|
||||||
|
dut.clockDomain.forkStimulus(10)
|
||||||
|
dut.debugClockDomain.forkStimulus(10)
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
ram.memory.loadBin(0x80000000l, "src/test/cpp/raw/smp/build/smp.bin")
|
||||||
|
|
||||||
|
sleep(10000*10)
|
||||||
|
simSuccess()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
*.map
|
||||||
|
*.v
|
||||||
|
*.elf
|
||||||
|
*.o
|
||||||
|
*.hex
|
|
@ -0,0 +1,108 @@
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
8000004c <success>:
|
||||||
|
8000004c: 00800513 li a0,8
|
||||||
|
80000050: 00052023 sw zero,0(a0)
|
||||||
|
80000054: 0100006f j 80000064 <end>
|
||||||
|
|
||||||
|
80000058 <failure>:
|
||||||
|
80000058: 00c00513 li a0,12
|
||||||
|
8000005c: 00052023 sw zero,0(a0)
|
||||||
|
80000060: 0040006f j 80000064 <end>
|
||||||
|
|
||||||
|
80000064 <end>:
|
||||||
|
80000064: 0000006f j 80000064 <end>
|
||||||
|
|
||||||
|
80000068 <sleep>:
|
||||||
|
80000068: fff50513 addi a0,a0,-1
|
||||||
|
8000006c: fe051ee3 bnez a0,80000068 <sleep>
|
||||||
|
80000070: 00008067 ret
|
||||||
|
|
||||||
|
80000074 <thread_count>:
|
||||||
|
80000074: 0000 unimp
|
||||||
|
...
|
||||||
|
|
||||||
|
80000078 <shared_memory_1>:
|
||||||
|
80000078: 0000 unimp
|
||||||
|
...
|
||||||
|
|
||||||
|
8000007c <test1_data>:
|
||||||
|
8000007c: 0000000b 0xb
|
||||||
|
|
||||||
|
80000080 <test2_data>:
|
||||||
|
80000080: 0016 c.slli zero,0x5
|
||||||
|
...
|
||||||
|
|
||||||
|
80000084 <test3_data>:
|
||||||
|
80000084: 0049 c.nop 18
|
||||||
|
...
|
||||||
|
|
||||||
|
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
|
|
@ -0,0 +1,5 @@
|
||||||
|
PROJ_NAME=smp
|
||||||
|
|
||||||
|
ATOMIC=yes
|
||||||
|
|
||||||
|
include ../common/asm.mk
|
|
@ -0,0 +1,70 @@
|
||||||
|
#define REPORT_OFFSET 0xF0000000
|
||||||
|
#define REPORT_THREAD_ID 0
|
||||||
|
#define REPORT_THREAD_COUNT 1
|
||||||
|
#define REPORT_SUCCESS 2
|
||||||
|
#define REPORT_FAILURE 3
|
||||||
|
|
||||||
|
#define report(reg, id) \
|
||||||
|
li a0, id*4; \
|
||||||
|
sw reg, 0(a0); \
|
||||||
|
|
||||||
|
_start:
|
||||||
|
|
||||||
|
#define HART_ID x20
|
||||||
|
csrr HART_ID, mhartid
|
||||||
|
la a0, test1_data
|
||||||
|
report(a0, REPORT_THREAD_ID)
|
||||||
|
|
||||||
|
|
||||||
|
count_thread_start:
|
||||||
|
//Count up threads
|
||||||
|
li a0, 1
|
||||||
|
la a1, thread_count
|
||||||
|
amoadd.w x0, a0, (a1)
|
||||||
|
|
||||||
|
count_thread_wait:
|
||||||
|
//Wait everybody
|
||||||
|
lw s0, thread_count
|
||||||
|
li a0, 200
|
||||||
|
call sleep
|
||||||
|
lw s1, thread_count
|
||||||
|
bne s1, s0, count_thread_wait
|
||||||
|
report(s1, REPORT_THREAD_ID)
|
||||||
|
|
||||||
|
j success
|
||||||
|
|
||||||
|
success:
|
||||||
|
report(x0, REPORT_SUCCESS)
|
||||||
|
j end
|
||||||
|
|
||||||
|
failure:
|
||||||
|
report(x0, REPORT_FAILURE)
|
||||||
|
j end
|
||||||
|
|
||||||
|
end:
|
||||||
|
j end
|
||||||
|
|
||||||
|
|
||||||
|
sleep:
|
||||||
|
addi a0, a0, -1
|
||||||
|
bnez a0, sleep
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
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
|
|
@ -0,0 +1,16 @@
|
||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
onChipRam (W!RX)/*(RX)*/ : ORIGIN = 0x80000000, LENGTH = 128K
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
|
||||||
|
.crt_section :
|
||||||
|
{
|
||||||
|
. = ALIGN(4);
|
||||||
|
*crt.o(.text)
|
||||||
|
} > onChipRam
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue