diff --git a/README.md b/README.md index fc9bca0..ddbf33b 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala b/src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala new file mode 100644 index 0000000..d824dc8 --- /dev/null +++ b/src/main/scala/vexriscv/demo/CustomCsrDemoPlugin.scala @@ -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 + } + } +} diff --git a/src/main/scala/vexriscv/demo/DhrystoneBench.scala b/src/main/scala/vexriscv/demo/DhrystoneBench.scala index 9cebd0e..19af427 100644 --- a/src/main/scala/vexriscv/demo/DhrystoneBench.scala +++ b/src/main/scala/vexriscv/demo/DhrystoneBench.scala @@ -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", diff --git a/src/main/scala/vexriscv/demo/GenCustomCsr.scala b/src/main/scala/vexriscv/demo/GenCustomCsr.scala new file mode 100644 index 0000000..5357f5d --- /dev/null +++ b/src/main/scala/vexriscv/demo/GenCustomCsr.scala @@ -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()) +} diff --git a/src/main/scala/vexriscv/demo/GenNoCacheNoMmuMaxPerf.scala b/src/main/scala/vexriscv/demo/GenNoCacheNoMmuMaxPerf.scala new file mode 100644 index 0000000..1171710 --- /dev/null +++ b/src/main/scala/vexriscv/demo/GenNoCacheNoMmuMaxPerf.scala @@ -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()) +} diff --git a/src/main/scala/vexriscv/demo/SynthesisBench.scala b/src/main/scala/vexriscv/demo/SynthesisBench.scala index 0e2da7d..7a64b6b 100644 --- a/src/main/scala/vexriscv/demo/SynthesisBench.scala +++ b/src/main/scala/vexriscv/demo/SynthesisBench.scala @@ -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" diff --git a/src/main/scala/vexriscv/plugin/CsrPlugin.scala b/src/main/scala/vexriscv/plugin/CsrPlugin.scala index b68d242..b64effe 100644 --- a/src/main/scala/vexriscv/plugin/CsrPlugin.scala +++ b/src/main/scala/vexriscv/plugin/CsrPlugin.scala @@ -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) diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.asm b/src/test/cpp/custom/custom_csr/build/custom_csr.asm new file mode 100644 index 0000000..75f34a9 --- /dev/null +++ b/src/test/cpp/custom/custom_csr/build/custom_csr.asm @@ -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 + 1c: 02311c63 bne sp,gp,54 + 20: 00200e13 li t3,2 + 24: 005dc0b7 lui ra,0x5dc + 28: 98a08093 addi ra,ra,-1654 # 5db98a + 2c: b0409073 csrw mhpmcounter4,ra + 30: b0402173 csrr sp,mhpmcounter4 + 34: 02209063 bne ra,sp,54 + 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 + 4c: 00315463 ble gp,sp,54 + 50: 0100006f j 60 + +00000054 : + 54: f0100137 lui sp,0xf0100 + 58: f2410113 addi sp,sp,-220 # f00fff24 + 5c: 01c12023 sw t3,0(sp) + +00000060 : + 60: f0100137 lui sp,0xf0100 + 64: f2010113 addi sp,sp,-224 # f00fff20 + 68: 00012023 sw zero,0(sp) + 6c: 00000013 nop + 70: 00000013 nop + 74: 00000013 nop + 78: 00000013 nop + 7c: 00000013 nop + 80: 00000013 nop diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.elf b/src/test/cpp/custom/custom_csr/build/custom_csr.elf new file mode 100755 index 0000000..71499ba Binary files /dev/null and b/src/test/cpp/custom/custom_csr/build/custom_csr.elf differ diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.hex b/src/test/cpp/custom/custom_csr/build/custom_csr.hex new file mode 100644 index 0000000..6249a34 --- /dev/null +++ b/src/test/cpp/custom/custom_csr/build/custom_csr.hex @@ -0,0 +1,10 @@ +:10000000130E1000F32040B0732140B0F32140B034 +:100010009380200013011100639E3002631C3102A3 +:10002000130E2000B7C05D009380A098739040B07D +:10003000732140B063902002130E3000F32050B0C3 +:10004000732150B0F32150B063D6200063543100C7 +:100050006F000001370110F0130141F22320C101AC +:10006000370110F0130101F22320010013000000FA +:100070001300000013000000130000001300000034 +:040080001300000069 +:00000001FF diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.map b/src/test/cpp/custom/custom_csr/build/custom_csr.map new file mode 100644 index 0000000..4fcd019 --- /dev/null +++ b/src/test/cpp/custom/custom_csr/build/custom_csr.map @@ -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 diff --git a/src/test/cpp/custom/custom_csr/build/custom_csr.v b/src/test/cpp/custom/custom_csr/build/custom_csr.v new file mode 100755 index 0000000..047524e --- /dev/null +++ b/src/test/cpp/custom/custom_csr/build/custom_csr.v @@ -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 diff --git a/src/test/cpp/custom/custom_csr/makefile b/src/test/cpp/custom/custom_csr/makefile new file mode 100644 index 0000000..5621ec5 --- /dev/null +++ b/src/test/cpp/custom/custom_csr/makefile @@ -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) + + diff --git a/src/test/cpp/custom/custom_csr/src/crt.S b/src/test/cpp/custom/custom_csr/src/crt.S new file mode 100644 index 0000000..16494a2 --- /dev/null +++ b/src/test/cpp/custom/custom_csr/src/crt.S @@ -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 diff --git a/src/test/cpp/custom/custom_csr/src/ld b/src/test/cpp/custom/custom_csr/src/ld new file mode 100644 index 0000000..8d95523 --- /dev/null +++ b/src/test/cpp/custom/custom_csr/src/ld @@ -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 + +} diff --git a/src/test/cpp/regression/main.cpp b/src/test/cpp/regression/main.cpp index 06345f2..390ca53 100644 --- a/src/test/cpp/regression/main.cpp +++ b/src/test/cpp/regression/main.cpp @@ -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);); diff --git a/src/test/cpp/regression/makefile b/src/test/cpp/regression/makefile index 04555fc..3caee62 100644 --- a/src/test/cpp/regression/makefile +++ b/src/test/cpp/regression/makefile @@ -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