mirror of
https://github.com/SpinalHDL/VexRiscv.git
synced 2025-01-03 03:43:39 -05:00
Add CsrInterface to allow custom CSR addition
Add CustomCsrDemoPlugin as a show case
This commit is contained in:
parent
42e677ec0d
commit
30b05eaf96
17 changed files with 470 additions and 43 deletions
|
@ -84,7 +84,6 @@ VexRiscv full max perf -> (RV32IM, 1.40 DMIPS/Mhz, 16KB-I$,16KB-D$, single cycle
|
|||
Cyclone V -> 90 Mhz 1,261 ALMs
|
||||
Cyclone IV -> 88 Mhz 2,780 LUT 1,788 FF
|
||||
|
||||
|
||||
VexRiscv full with MMU (RV32IM, 1.17 DMIPS/Mhz with cache trashing, 4KB-I$, 4KB-D$, single cycle barrel shifter, debug module, catch exceptions, dynamic branch, MMU) ->
|
||||
Artix 7 -> 223 Mhz 2085 LUT 2020 FF
|
||||
Cyclone V -> 110 Mhz 1,503 ALMs
|
||||
|
|
36
src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala
Normal file
36
src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala
Normal file
|
@ -0,0 +1,36 @@
|
|||
package vexriscv.demo
|
||||
|
||||
import spinal.core._
|
||||
import vexriscv.plugin.{CsrInterface, Plugin}
|
||||
import vexriscv.{DecoderService, Stageable, VexRiscv}
|
||||
|
||||
|
||||
case class CustomCsrDemoArea(csrService : CsrInterface) extends Area{
|
||||
val instructionCounter = Reg(UInt(32 bits))
|
||||
val cycleCounter = Reg(UInt(32 bits))
|
||||
|
||||
csrService.rw(0xB04, instructionCounter)
|
||||
csrService.r(0xB05, cycleCounter)
|
||||
}
|
||||
|
||||
class CustomCsrDemoPlugin extends Plugin[VexRiscv]{
|
||||
var csrStruct : CustomCsrDemoArea = null
|
||||
|
||||
//Callback to setup the plugin and ask for different services
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
|
||||
val csrService = pipeline.service(classOf[CsrInterface])
|
||||
csrStruct = pipeline plug CustomCsrDemoArea(csrService)
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
||||
csrStruct.cycleCounter := csrStruct.cycleCounter + 1
|
||||
when(writeBack.arbitration.isFiring) {
|
||||
csrStruct.instructionCounter := csrStruct.instructionCounter + 1
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,17 +50,22 @@ object DhrystoneBench extends App{
|
|||
)
|
||||
|
||||
getDmips(
|
||||
name = "GenFullNoMmu",
|
||||
gen = GenFullNoMmu.main(null),
|
||||
test = "make clean run REDO=0 MMU=no "
|
||||
name = "GenNoCacheNoMmuMaxPerf",
|
||||
gen = GenNoCacheNoMmuMaxPerf.main(null),
|
||||
test = "make clean run REDO=0 MMU=no CSR=no DBUS=SIMPLE IBUS=SIMPLE"
|
||||
)
|
||||
|
||||
|
||||
getDmips(
|
||||
name = "GenFullNoMmuMaxPerf",
|
||||
gen = GenFullNoMmuMaxPerf.main(null),
|
||||
test = "make clean run REDO=0 MMU=no"
|
||||
)
|
||||
|
||||
getDmips(
|
||||
name = "GenFullNoMmu",
|
||||
gen = GenFullNoMmu.main(null),
|
||||
test = "make clean run REDO=0 MMU=no "
|
||||
)
|
||||
|
||||
getDmips(
|
||||
name = "GenFull",
|
||||
|
|
62
src/main/scala/vexriscv/demo/GenCustomCsr.scala
Normal file
62
src/main/scala/vexriscv/demo/GenCustomCsr.scala
Normal file
|
@ -0,0 +1,62 @@
|
|||
package vexriscv.demo
|
||||
|
||||
import spinal.core._
|
||||
import vexriscv.plugin._
|
||||
import vexriscv.{VexRiscv, VexRiscvConfig, plugin}
|
||||
|
||||
/**
|
||||
* Created by spinalvm on 15.06.17.
|
||||
*/
|
||||
|
||||
//make clean run DBUS=SIMPLE IBUS=SIMPLE CSR=no MMU=no DEBUG_PLUGIN=no MUL=no DIV=no
|
||||
object GenCustomCsr extends App{
|
||||
def cpu() = new VexRiscv(
|
||||
config = VexRiscvConfig(
|
||||
plugins = List(
|
||||
new CustomCsrDemoPlugin,
|
||||
new CsrPlugin(CsrPluginConfig.small),
|
||||
new PcManagerSimplePlugin(
|
||||
resetVector = 0x00000000l,
|
||||
relaxedPcCalculation = false
|
||||
),
|
||||
new IBusSimplePlugin(
|
||||
interfaceKeepData = false,
|
||||
catchAccessFault = false
|
||||
),
|
||||
new DBusSimplePlugin(
|
||||
catchAddressMisaligned = false,
|
||||
catchAccessFault = false
|
||||
),
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = false
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = plugin.SYNC,
|
||||
zeroBoot = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin(
|
||||
separatedAddSub = false,
|
||||
executeInsertion = false
|
||||
),
|
||||
new FullBarrielShifterPlugin,
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = true,
|
||||
bypassMemory = true,
|
||||
bypassWriteBack = true,
|
||||
bypassWriteBackBuffer = true,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
),
|
||||
new BranchPlugin(
|
||||
earlyBranch = false,
|
||||
catchAddressMisaligned = false,
|
||||
prediction = NONE
|
||||
),
|
||||
new YamlPlugin("cpu0.yaml")
|
||||
)
|
||||
)
|
||||
)
|
||||
SpinalVerilog(cpu())
|
||||
}
|
69
src/main/scala/vexriscv/demo/GenNoCacheNoMmuMaxPerf.scala
Normal file
69
src/main/scala/vexriscv/demo/GenNoCacheNoMmuMaxPerf.scala
Normal file
|
@ -0,0 +1,69 @@
|
|||
package vexriscv.demo
|
||||
|
||||
import spinal.core._
|
||||
import vexriscv.ip.{DataCacheConfig, InstructionCacheConfig}
|
||||
import vexriscv.plugin._
|
||||
import vexriscv.{VexRiscv, VexRiscvConfig, plugin}
|
||||
|
||||
/**
|
||||
* Created by spinalvm on 15.06.17.
|
||||
*/
|
||||
object GenNoCacheNoMmuMaxPerf extends App{
|
||||
def cpu() = new VexRiscv(
|
||||
config = VexRiscvConfig(
|
||||
plugins = List(
|
||||
new PcManagerSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
relaxedPcCalculation = false
|
||||
),
|
||||
new IBusSimplePlugin(
|
||||
interfaceKeepData = false,
|
||||
catchAccessFault = true
|
||||
),
|
||||
new DBusSimplePlugin(
|
||||
catchAddressMisaligned = true,
|
||||
catchAccessFault = true,
|
||||
earlyInjection = false
|
||||
),
|
||||
new StaticMemoryTranslatorPlugin(
|
||||
ioRange = _(31 downto 28) === 0xF
|
||||
),
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = true
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = plugin.SYNC,
|
||||
zeroBoot = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin(
|
||||
separatedAddSub = false,
|
||||
executeInsertion = true
|
||||
),
|
||||
new FullBarrielShifterPlugin(earlyInjection = true),
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = true,
|
||||
bypassMemory = true,
|
||||
bypassWriteBack = true,
|
||||
bypassWriteBackBuffer = true,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
),
|
||||
new MulPlugin,
|
||||
new DivPlugin,
|
||||
new CsrPlugin(CsrPluginConfig.small),
|
||||
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
|
||||
new BranchPlugin(
|
||||
earlyBranch = true,
|
||||
catchAddressMisaligned = true,
|
||||
prediction = DYNAMIC_TARGET,
|
||||
historyRamSizeLog2 = 8
|
||||
),
|
||||
new YamlPlugin("cpu0.yaml")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
SpinalVerilog(cpu())
|
||||
}
|
|
@ -37,6 +37,12 @@ object VexRiscvSynthesisBench {
|
|||
SpinalVerilog(GenFullNoMmu.cpu().setDefinitionName(getRtlPath().split("\\.").head))
|
||||
}
|
||||
|
||||
val noCacheNoMmuMaxPerf= new Rtl {
|
||||
override def getName(): String = "VexRiscv no cache no MMU max perf"
|
||||
override def getRtlPath(): String = "VexRiscvNoCacheNoMmuMaxPerf.v"
|
||||
SpinalVerilog(GenNoCacheNoMmuMaxPerf.cpu().setDefinitionName(getRtlPath().split("\\.").head))
|
||||
}
|
||||
|
||||
val fullNoMmuMaxPerf= new Rtl {
|
||||
override def getName(): String = "VexRiscv full no MMU max perf"
|
||||
override def getRtlPath(): String = "VexRiscvFullNoMmuMaxPerf.v"
|
||||
|
@ -49,8 +55,8 @@ object VexRiscvSynthesisBench {
|
|||
SpinalVerilog(GenFull.cpu().setDefinitionName(getRtlPath().split("\\.").head))
|
||||
}
|
||||
|
||||
// val rtls = List(smallestNoCsr, smallest, smallAndProductive, fullNoMmuNoCache, fullNoMmuMaxPerf, fullNoMmu, full)
|
||||
val rtls = List(fullNoMmuMaxPerf)
|
||||
// val rtls = List(smallestNoCsr, smallest, smallAndProductive, fullNoMmuNoCache, noCacheNoMmuMaxPerf, fullNoMmuMaxPerf, fullNoMmu, full)
|
||||
val rtls = List(noCacheNoMmuMaxPerf, fullNoMmuMaxPerf)
|
||||
|
||||
val targets = XilinxStdTargets(
|
||||
vivadoArtix7Path = "/eda/Xilinx/Vivado/2017.2/bin"
|
||||
|
|
|
@ -9,8 +9,8 @@ import scala.collection.mutable.ArrayBuffer
|
|||
import scala.collection.mutable
|
||||
|
||||
/**
|
||||
* Created by spinalvm on 21.03.17.
|
||||
*/
|
||||
* Created by spinalvm on 21.03.17.
|
||||
*/
|
||||
|
||||
trait CsrAccess{
|
||||
def canWrite : Boolean = false
|
||||
|
@ -32,25 +32,25 @@ object CsrAccess {
|
|||
|
||||
case class ExceptionPortInfo(port : Flow[ExceptionCause],stage : Stage, priority : Int)
|
||||
case class CsrPluginConfig(
|
||||
catchIllegalAccess : Boolean,
|
||||
mvendorid : BigInt,
|
||||
marchid : BigInt,
|
||||
mimpid : BigInt,
|
||||
mhartid : BigInt,
|
||||
misaExtensionsInit : Int,
|
||||
misaAccess : CsrAccess,
|
||||
mtvecAccess : CsrAccess,
|
||||
mtvecInit : BigInt,
|
||||
mepcAccess : CsrAccess,
|
||||
mscratchGen : Boolean,
|
||||
mcauseAccess : CsrAccess,
|
||||
mbadaddrAccess : CsrAccess,
|
||||
mcycleAccess : CsrAccess,
|
||||
minstretAccess : CsrAccess,
|
||||
ucycleAccess : CsrAccess,
|
||||
wfiGen : Boolean,
|
||||
ecallGen : Boolean
|
||||
){
|
||||
catchIllegalAccess : Boolean,
|
||||
mvendorid : BigInt,
|
||||
marchid : BigInt,
|
||||
mimpid : BigInt,
|
||||
mhartid : BigInt,
|
||||
misaExtensionsInit : Int,
|
||||
misaAccess : CsrAccess,
|
||||
mtvecAccess : CsrAccess,
|
||||
mtvecInit : BigInt,
|
||||
mepcAccess : CsrAccess,
|
||||
mscratchGen : Boolean,
|
||||
mcauseAccess : CsrAccess,
|
||||
mbadaddrAccess : CsrAccess,
|
||||
mcycleAccess : CsrAccess,
|
||||
minstretAccess : CsrAccess,
|
||||
ucycleAccess : CsrAccess,
|
||||
wfiGen : Boolean,
|
||||
ecallGen : Boolean
|
||||
){
|
||||
assert(!ucycleAccess.canWrite)
|
||||
}
|
||||
|
||||
|
@ -121,11 +121,22 @@ object CsrPluginConfig{
|
|||
}
|
||||
case class CsrWrite(that : Data, bitOffset : Int)
|
||||
case class CsrRead(that : Data , bitOffset : Int)
|
||||
case class CsrMapping(){
|
||||
case class CsrMapping() extends CsrInterface{
|
||||
val mapping = mutable.HashMap[Int,ArrayBuffer[Any]]()
|
||||
def addMappingAt(address : Int,that : Any) = mapping.getOrElseUpdate(address,new ArrayBuffer[Any]) += that
|
||||
def r(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrRead(that,bitOffset))
|
||||
def w(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrWrite(that,bitOffset))
|
||||
}
|
||||
|
||||
|
||||
trait IContextSwitching{
|
||||
def isContextSwitching : Bool
|
||||
}
|
||||
|
||||
|
||||
trait CsrInterface{
|
||||
def r(csrAddress : Int, bitOffset : Int, that : Data): Unit
|
||||
def w(csrAddress : Int, bitOffset : Int, that : Data): Unit
|
||||
def rw(csrAddress : Int, bitOffset : Int,that : Data): Unit ={
|
||||
r(csrAddress,bitOffset,that)
|
||||
w(csrAddress,bitOffset,that)
|
||||
|
@ -138,13 +149,7 @@ case class CsrMapping(){
|
|||
}
|
||||
|
||||
|
||||
trait IContextSwitching{
|
||||
def isContextSwitching : Bool
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with ExceptionService with PrivilegeService with InterruptionInhibitor with ExceptionInhibitor with IContextSwitching{
|
||||
class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with ExceptionService with PrivilegeService with InterruptionInhibitor with ExceptionInhibitor with IContextSwitching with CsrInterface{
|
||||
import config._
|
||||
import CsrAccess._
|
||||
|
||||
|
@ -179,6 +184,13 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|
|||
|
||||
var allowInterrupts : Bool = null
|
||||
var allowException : Bool = null
|
||||
|
||||
val csrMapping = new CsrMapping()
|
||||
|
||||
|
||||
override def r(csrAddress: Int, bitOffset: Int, that: Data): Unit = csrMapping.r(csrAddress, bitOffset, that)
|
||||
override def w(csrAddress: Int, bitOffset: Int, that: Data): Unit = csrMapping.w(csrAddress, bitOffset, that)
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
|
||||
|
@ -210,7 +222,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|
|||
CSRRWI -> immediatActions,
|
||||
CSRRSI -> immediatActions,
|
||||
CSRRCI -> immediatActions,
|
||||
// EBREAK -> (defaultEnv ++ List(ENV_CTRL -> EnvCtrlEnum.EBREAK)), //TODO
|
||||
// EBREAK -> (defaultEnv ++ List(ENV_CTRL -> EnvCtrlEnum.EBREAK)), //TODO
|
||||
MRET -> (defaultEnv ++ List(ENV_CTRL -> EnvCtrlEnum.MRET))
|
||||
))
|
||||
if(wfiGen) decoderService.add(WFI, defaultEnv ++ List(ENV_CTRL -> EnvCtrlEnum.WFI))
|
||||
|
@ -252,7 +264,6 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|
|||
|
||||
pipeline plug new Area{
|
||||
//Define CSR mapping utilities
|
||||
val csrMapping = new CsrMapping()
|
||||
implicit class CsrAccessPimper(csrAccess : CsrAccess){
|
||||
def apply(csrAddress : Int, thats : (Int, Data)*) : Unit = {
|
||||
if(csrAccess == `WRITE_ONLY` || csrAccess == `READ_WRITE`) for(that <- thats) csrMapping.w(csrAddress,that._1, that._2)
|
||||
|
@ -452,11 +463,9 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|
|||
execute plug new Area {
|
||||
import execute._
|
||||
|
||||
val illegalAccess = arbitration.isValid && input(IS_CSR)
|
||||
val illegalAccess = True
|
||||
if(catchIllegalAccess) {
|
||||
val illegalInstruction = arbitration.isValid && privilege === 0 && (input(ENV_CTRL) === EnvCtrlEnum.EBREAK || input(ENV_CTRL) === EnvCtrlEnum.MRET)
|
||||
|
||||
selfException.valid := illegalAccess || illegalInstruction
|
||||
selfException.valid := arbitration.isValid && input(IS_CSR) && illegalAccess
|
||||
selfException.code := 2
|
||||
selfException.badAddr.assignDontCare()
|
||||
}
|
||||
|
@ -471,7 +480,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|
|||
True -> Mux(input(INSTRUCTION)(12), readDataReg & ~writeSrc, readDataReg | writeSrc)
|
||||
)
|
||||
val writeOpcode = (!((input(INSTRUCTION)(14 downto 13) === "01" && input(INSTRUCTION)(rs1Range) === 0)
|
||||
|| (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0)))
|
||||
|| (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0)))
|
||||
val writeInstruction = arbitration.isValid && input(IS_CSR) && writeOpcode
|
||||
|
||||
arbitration.haltItself setWhen(writeInstruction && !readDataRegValid)
|
||||
|
|
44
src/test/cpp/custom/custom_csr/build/custom_csr.asm
Normal file
44
src/test/cpp/custom/custom_csr/build/custom_csr.asm
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
build/custom_csr.elf: file format elf32-littleriscv
|
||||
|
||||
|
||||
Disassembly of section .crt_section:
|
||||
|
||||
00000000 <_start>:
|
||||
0: 00100e13 li t3,1
|
||||
4: b04020f3 csrr ra,mhpmcounter4
|
||||
8: b0402173 csrr sp,mhpmcounter4
|
||||
c: b04021f3 csrr gp,mhpmcounter4
|
||||
10: 00208093 addi ra,ra,2
|
||||
14: 00110113 addi sp,sp,1
|
||||
18: 02309e63 bne ra,gp,54 <fail>
|
||||
1c: 02311c63 bne sp,gp,54 <fail>
|
||||
20: 00200e13 li t3,2
|
||||
24: 005dc0b7 lui ra,0x5dc
|
||||
28: 98a08093 addi ra,ra,-1654 # 5db98a <pass+0x5db92a>
|
||||
2c: b0409073 csrw mhpmcounter4,ra
|
||||
30: b0402173 csrr sp,mhpmcounter4
|
||||
34: 02209063 bne ra,sp,54 <fail>
|
||||
38: 00300e13 li t3,3
|
||||
3c: b05020f3 csrr ra,mhpmcounter5
|
||||
40: b0502173 csrr sp,mhpmcounter5
|
||||
44: b05021f3 csrr gp,mhpmcounter5
|
||||
48: 0020d663 ble sp,ra,54 <fail>
|
||||
4c: 00315463 ble gp,sp,54 <fail>
|
||||
50: 0100006f j 60 <pass>
|
||||
|
||||
00000054 <fail>:
|
||||
54: f0100137 lui sp,0xf0100
|
||||
58: f2410113 addi sp,sp,-220 # f00fff24 <pass+0xf00ffec4>
|
||||
5c: 01c12023 sw t3,0(sp)
|
||||
|
||||
00000060 <pass>:
|
||||
60: f0100137 lui sp,0xf0100
|
||||
64: f2010113 addi sp,sp,-224 # f00fff20 <pass+0xf00ffec0>
|
||||
68: 00012023 sw zero,0(sp)
|
||||
6c: 00000013 nop
|
||||
70: 00000013 nop
|
||||
74: 00000013 nop
|
||||
78: 00000013 nop
|
||||
7c: 00000013 nop
|
||||
80: 00000013 nop
|
BIN
src/test/cpp/custom/custom_csr/build/custom_csr.elf
Executable file
BIN
src/test/cpp/custom/custom_csr/build/custom_csr.elf
Executable file
Binary file not shown.
10
src/test/cpp/custom/custom_csr/build/custom_csr.hex
Normal file
10
src/test/cpp/custom/custom_csr/build/custom_csr.hex
Normal file
|
@ -0,0 +1,10 @@
|
|||
:10000000130E1000F32040B0732140B0F32140B034
|
||||
:100010009380200013011100639E3002631C3102A3
|
||||
:10002000130E2000B7C05D009380A098739040B07D
|
||||
:10003000732140B063902002130E3000F32050B0C3
|
||||
:10004000732150B0F32150B063D6200063543100C7
|
||||
:100050006F000001370110F0130141F22320C101AC
|
||||
:10006000370110F0130101F22320010013000000FA
|
||||
:100070001300000013000000130000001300000034
|
||||
:040080001300000069
|
||||
:00000001FF
|
30
src/test/cpp/custom/custom_csr/build/custom_csr.map
Normal file
30
src/test/cpp/custom/custom_csr/build/custom_csr.map
Normal file
|
@ -0,0 +1,30 @@
|
|||
|
||||
Memory Configuration
|
||||
|
||||
Name Origin Length Attributes
|
||||
onChipRam 0x0000000000000000 0x0000000000002000 w !xr
|
||||
*default* 0x0000000000000000 0xffffffffffffffff
|
||||
|
||||
Linker script and memory map
|
||||
|
||||
LOAD build/src/crt.o
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/rv32i/ilp32/libgcc.a
|
||||
START GROUP
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/../../../../riscv64-unknown-elf/lib/rv32i/ilp32/libgloss.a
|
||||
END GROUP
|
||||
LOAD /opt/riscv/bin/../lib/gcc/riscv64-unknown-elf/7.1.1/rv32i/ilp32/libgcc.a
|
||||
0x0000000000000000 . = 0x0
|
||||
|
||||
.crt_section 0x0000000000000000 0x84
|
||||
0x0000000000000000 . = ALIGN (0x4)
|
||||
*crt.o(.text)
|
||||
.text 0x0000000000000000 0x84 build/src/crt.o
|
||||
0x0000000000000000 _start
|
||||
OUTPUT(build/custom_csr.elf elf32-littleriscv)
|
||||
|
||||
.data 0x0000000000000084 0x0
|
||||
.data 0x0000000000000084 0x0 build/src/crt.o
|
||||
|
||||
.bss 0x0000000000000084 0x0
|
||||
.bss 0x0000000000000084 0x0 build/src/crt.o
|
10
src/test/cpp/custom/custom_csr/build/custom_csr.v
Executable file
10
src/test/cpp/custom/custom_csr/build/custom_csr.v
Executable file
|
@ -0,0 +1,10 @@
|
|||
@00000000
|
||||
13 0E 10 00 F3 20 40 B0 73 21 40 B0 F3 21 40 B0
|
||||
93 80 20 00 13 01 11 00 63 9E 30 02 63 1C 31 02
|
||||
13 0E 20 00 B7 C0 5D 00 93 80 A0 98 73 90 40 B0
|
||||
73 21 40 B0 63 90 20 02 13 0E 30 00 F3 20 50 B0
|
||||
73 21 50 B0 F3 21 50 B0 63 D6 20 00 63 54 31 00
|
||||
6F 00 00 01 37 01 10 F0 13 01 41 F2 23 20 C1 01
|
||||
37 01 10 F0 13 01 01 F2 23 20 01 00 13 00 00 00
|
||||
13 00 00 00 13 00 00 00 13 00 00 00 13 00 00 00
|
||||
13 00 00 00
|
73
src/test/cpp/custom/custom_csr/makefile
Normal file
73
src/test/cpp/custom/custom_csr/makefile
Normal file
|
@ -0,0 +1,73 @@
|
|||
PROJ_NAME=custom_csr
|
||||
|
||||
|
||||
RISCV_PATH=/opt/riscv/
|
||||
CFLAGS += -march=rv32i -mabi=ilp32
|
||||
RISCV_NAME = riscv64-unknown-elf
|
||||
RISCV_OBJCOPY = $(RISCV_PATH)/bin/$(RISCV_NAME)-objcopy
|
||||
RISCV_OBJDUMP = $(RISCV_PATH)/bin/$(RISCV_NAME)-objdump
|
||||
RISCV_CLIB=$(RISCV_PATH)$(RISCV_NAME)/lib/
|
||||
RISCV_CC=$(RISCV_PATH)/bin/$(RISCV_NAME)-gcc
|
||||
LDSCRIPT=src/ld
|
||||
|
||||
|
||||
SRCS = $(wildcard src/*.c) \
|
||||
$(wildcard src/*.cpp) \
|
||||
$(wildcard src/*.S)
|
||||
|
||||
|
||||
CFLAGS += -static
|
||||
LDFLAGS += -e_start -T $(LDSCRIPT) -nostartfiles -Wl,-Map,$(OBJDIR)/$(PROJ_NAME).map -Wl,--print-memory-usage
|
||||
OBJDIR = build
|
||||
OBJS := $(SRCS)
|
||||
OBJS := $(OBJS:.c=.o)
|
||||
OBJS := $(OBJS:.cpp=.o)
|
||||
OBJS := $(OBJS:.S=.o)
|
||||
OBJS := $(addprefix $(OBJDIR)/,$(OBJS))
|
||||
|
||||
|
||||
|
||||
all: $(OBJDIR)/$(PROJ_NAME).elf $(OBJDIR)/$(PROJ_NAME).hex $(OBJDIR)/$(PROJ_NAME).asm $(OBJDIR)/$(PROJ_NAME).v
|
||||
@echo "done"
|
||||
|
||||
$(OBJDIR)/%.elf: $(OBJS) | $(OBJDIR)
|
||||
$(RISCV_CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
|
||||
|
||||
%.hex: %.elf
|
||||
$(RISCV_OBJCOPY) -O ihex $^ $@
|
||||
|
||||
%.bin: %.elf
|
||||
$(RISCV_OBJCOPY) -O binary $^ $@
|
||||
|
||||
%.v: %.elf
|
||||
$(RISCV_OBJCOPY) -O verilog $^ $@
|
||||
|
||||
%.asm: %.elf
|
||||
$(RISCV_OBJDUMP) -S -d $^ > $@
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
mkdir -p $(dir $@)
|
||||
$(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
mkdir -p $(dir $@)
|
||||
$(RISCV_CC) -c $(CFLAGS) $(INC) -o $@ $^
|
||||
|
||||
$(OBJDIR)/%.o: %.S
|
||||
mkdir -p $(dir $@)
|
||||
$(RISCV_CC) -c $(CFLAGS) -o $@ $^ -D__ASSEMBLY__=1
|
||||
|
||||
$(OBJDIR):
|
||||
mkdir -p $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJDIR)/$(PROJ_NAME).elf
|
||||
rm -f $(OBJDIR)/$(PROJ_NAME).hex
|
||||
rm -f $(OBJDIR)/$(PROJ_NAME).map
|
||||
rm -f $(OBJDIR)/$(PROJ_NAME).v
|
||||
rm -f $(OBJDIR)/$(PROJ_NAME).asm
|
||||
find $(OBJDIR) -type f -name '*.o' -print0 | xargs -0 -r rm
|
||||
|
||||
.SECONDARY: $(OBJS)
|
||||
|
||||
|
48
src/test/cpp/custom/custom_csr/src/crt.S
Normal file
48
src/test/cpp/custom/custom_csr/src/crt.S
Normal file
|
@ -0,0 +1,48 @@
|
|||
.globl _start
|
||||
_start:
|
||||
|
||||
//Test 1
|
||||
li x28, 1
|
||||
csrr x1, 0xB04
|
||||
csrr x2, 0xB04
|
||||
csrr x3, 0xB04
|
||||
add x1, x1, 2
|
||||
add x2, x2, 1
|
||||
bne x1, x3, fail
|
||||
bne x2, x3, fail
|
||||
|
||||
|
||||
//Test 2
|
||||
li x28, 2
|
||||
li x1, 6142346
|
||||
csrw 0xB04, x1
|
||||
csrr x2, 0xB04
|
||||
bne x1, x2, fail
|
||||
|
||||
|
||||
//Test 3
|
||||
li x28, 3
|
||||
csrr x1, 0xB05
|
||||
csrr x2, 0xB05
|
||||
csrr x3, 0xB05
|
||||
bge x1, x2, fail
|
||||
bge x2, x3, fail
|
||||
|
||||
j pass
|
||||
|
||||
fail: //x28 => error code
|
||||
li x2, 0xF00FFF24
|
||||
sw x28, 0(x2)
|
||||
|
||||
pass:
|
||||
li x2, 0xF00FFF20
|
||||
sw x0, 0(x2)
|
||||
|
||||
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
17
src/test/cpp/custom/custom_csr/src/ld
Normal file
17
src/test/cpp/custom/custom_csr/src/ld
Normal file
|
@ -0,0 +1,17 @@
|
|||
OUTPUT_ARCH( "riscv" )
|
||||
|
||||
MEMORY {
|
||||
onChipRam (W!RX)/*(RX)*/ : ORIGIN = 0x00000000, LENGTH = 8K
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x000;
|
||||
|
||||
.crt_section :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*crt.o(.text)
|
||||
} > onChipRam
|
||||
|
||||
}
|
|
@ -1725,6 +1725,10 @@ int main(int argc, char **argv, char **env) {
|
|||
redo(REDO,Workspace("custom_simd_add").loadHex("../custom/simd_add/build/custom_simd_add.hex")->bootAt(0x00000000u)->run(50e3););
|
||||
#endif
|
||||
|
||||
#ifdef CUSTOM_CSR
|
||||
redo(REDO,Workspace("custom_csr").loadHex("../custom/custom_csr/build/custom_csr.hex")->bootAt(0x00000000u)->run(50e3););
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ATOMIC
|
||||
redo(REDO,Workspace("atomic").loadHex("../custom/atomic/build/atomic.hex")->bootAt(0x00000000u)->run(10e3););
|
||||
|
|
|
@ -12,6 +12,7 @@ ATOMIC?=no
|
|||
DEBUG_PLUGIN?=STD
|
||||
DEBUG_PLUGIN_EXTERNAL?=no
|
||||
CUSTOM_SIMD_ADD?=no
|
||||
CUSTOM_CSR?=no
|
||||
DHRYSTONE=yes
|
||||
FREERTOS=no
|
||||
REDO?=10
|
||||
|
@ -48,6 +49,10 @@ ifeq ($(CUSTOM_SIMD_ADD),yes)
|
|||
ADDCFLAGS += -CFLAGS -DCUSTOM_SIMD_ADD
|
||||
endif
|
||||
|
||||
ifeq ($(CUSTOM_CSR),yes)
|
||||
ADDCFLAGS += -CFLAGS -DCUSTOM_CSR
|
||||
endif
|
||||
|
||||
ifeq ($(TRACE_WITH_TIME),yes)
|
||||
ADDCFLAGS += -CFLAGS -DTRACE_WITH_TIME
|
||||
endif
|
||||
|
|
Loading…
Reference in a new issue