Skip to content

Commit

Permalink
SpinalHDL#60 Added automated linux regression in travis
Browse files Browse the repository at this point in the history
Fix DBusCached plugin access sharing for the MMU deadlock when exception is in the decode stage
Fix IBusSimplePlugin issues with used with non regular configs + MMU
Bring back the LinuxGen config into a light one
  • Loading branch information
Dolu1990 committed Apr 19, 2019
1 parent 2810ff0 commit e47b76f
Show file tree
Hide file tree
Showing 15 changed files with 222 additions and 82 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "src/test/resources/VexRiscvRegressionData"]
path = src/test/resources/VexRiscvRegressionData
url = ../VexRiscvRegressionData.git
15 changes: 9 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ scala:
sbt_args: -no-colors -J-Xss2m

script:
- export VEXRISCV_REGRESSION_CONFIG_COUNT=100
- export VEXRISCV_REGRESSION_FREERTOS_COUNT=no
- export VEXRISCV_REGRESSION_THREAD_COUNT=1
- sbt -jvm-opts travis/jvmopts.compile compile
- sbt -jvm-opts travis/jvmopts.test test

Expand All @@ -22,7 +22,11 @@ jdk:
# - openjdk7

env:
- secure: "v7FHP8yK/zixpv1ML05qcRhZfDVDFdTmTPjfMZHL7gmrJveVDgze22x4tY4tB1+JEXhKuVTYvimOrX/Ok+rOOT5gVKLowv4PUQwCR+HgWVIbqjcfZNLsa369v03/p4K/zbjJSiXFahZYOXa0ApED2KWHcVfCrNsPv0UF7YZGiIa1Q/lPBwfmpN1rLih2Mpgn4KVaJky22t7JXJyVrNdGVmIA51slVbyFwFAE8Ww/0tkC+i2PUcWWRMIxtXP4iyq/9Npcq5VdqOatKfWHqAElLfKSPNMYLMlcyxyNpNx4paq8cL6fQxFcBLi9M2msz2i/qpKv30a0tzNo5bQQgucAXOQJB2Buks728upLuqsr+k25hwcqrtjyMOr9UQkt7qXAJH/0kimW7aW1yoMxbm/6mNG98X9D1EzNRewHAKatwJeFy1bw5qIuSQxPBwQMGloManrHOHGotmHKk7Y+dgM/z1UlaAdxSQuKWGXBc8QlQvif8puPYEdJMoInJNRxiWfYu06XnmzTXgMketK7RdULM9DVYzw8hzS2EIWKu8Oa0zn0PTevD2YeJNd4G8mDqO0vz5hloIc7pFsq/exQUB/kFozfCsnvhW8P+MPN0LpuSpptBQTsLWbM5BH0hd46HoWcneDdlMvVrUcgsTPmmSroIkLIEUo+Y2iN5eQHPPp85Cw="
- VEXRISCV_REGRESSION_CONFIG_COUNT=0
- VEXRISCV_REGRESSION_CONFIG_COUNT=5
- VEXRISCV_REGRESSION_CONFIG_COUNT=5
- VEXRISCV_REGRESSION_CONFIG_COUNT=5
- VEXRISCV_REGRESSION_CONFIG_COUNT=5

before_install:
# JDK fix
Expand All @@ -34,11 +38,9 @@ before_install:

# Verilator
- sudo apt-get install git make autoconf g++ flex bison -y # First time prerequisites
- git clone http://git.veripool.org/git/verilator # Only first time
- unset VERILATOR_ROOT # For bash
- wget https://www.veripool.org/ftp/verilator-4.012.tgz
- tar xvzf verilator*.t*gz
- cd verilator
- git pull # Make sure we're up-to-date
- git checkout verilator_3_916
- autoconf # Create ./configure script
- ./configure
- make -j$(nproc)
Expand All @@ -48,6 +50,7 @@ before_install:
- git clone https://github.com/SpinalHDL/SpinalHDL.git -b dev

- cd VexRiscv
- git submodule update --init --recursive
#- curl -T README.md -udolu1990:$BINTRAY_KEY https://api.bintray.com/content/spinalhdl/VexRiscv/test/0.0.4/README.md
#- curl -X POST -udolu1990:$BINTRAY_KEY https://api.bintray.com/content/spinalhdl/VexRiscv/test/0.0.4/publish
#- sbt compile
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/vexriscv/Services.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ case class ExceptionCause() extends Bundle{

trait ExceptionService{
def newExceptionPort(stage : Stage, priority : Int = 0) : Flow[ExceptionCause]
def isExceptionPending() : Bool
def isExceptionPending(stage : Stage) : Bool
}

trait PrivilegeService{
Expand Down
16 changes: 9 additions & 7 deletions src/main/scala/vexriscv/demo/Linux.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ cd VexRiscv
Run regressions =>
sbt "runMain vexriscv.demo.LinuxGen -r"
cd src/test/cpp/regression
make run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yes SUPERVISOR=yes CSR=yes COMPRESSED=no LRSC=yes AMO=yes REDO=10 TRACE=no
make clean run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yes SUPERVISOR=yes MMU=yes CSR=yes COMPRESSED=no MUL=yes DIV=yes LRSC=yes AMO=yes REDO=10 TRACE=no COREMARK=yes LINUX_REGRESSION=yes
Run linux in simulation (Require the machime mode emulator compiled in SIM mode) =>
sbt "runMain vexriscv.demo.LinuxGen"
cd src/test/cpp/regression
export BUILDROOT=/home/miaou/pro/riscv/buildrootSpinal
make run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD SUPERVISOR=yes CSR=yes COMPRESSED=no LRSC=yes AMO=yes REDO=0 DHRYSTONE=no LINUX_SOC=yes EMULATOR=../../../main/c/emulator/build/emulator.bin VMLINUX=$BUILDROOT/output/images/Image DTB=$BUILDROOT/board/spinal/vexriscv_sim/rv32.dtb RAMDISK=$BUILDROOT/output/images/rootfs.cpio TRACE=no FLOW_INFO=no
make clean run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD SUPERVISOR=yes CSR=yes COMPRESSED=no LRSC=yes AMO=yes REDO=0 DHRYSTONE=no LINUX_SOC=yes EMULATOR=../../../main/c/emulator/build/emulator.bin VMLINUX=$BUILDROOT/output/images/Image DTB=$BUILDROOT/board/spinal/vexriscv_sim/rv32.dtb RAMDISK=$BUILDROOT/output/images/rootfs.cpio WITH_USER_IO=yes TRACE=no FLOW_INFO=no
Run linux with QEMU (Require the machime mode emulator compiled in QEMU mode)
export BUILDROOT=/home/miaou/pro/riscv/buildrootSpinal
Expand Down Expand Up @@ -94,10 +94,12 @@ rm VexRiscv.v
cp $DATA/VexRiscv.v ../../../..
make run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD SUPERVISOR=yes CSR=yes COMPRESSED=no LRSC=yes AMO=yes REDO=0 DHRYSTONE=no LINUX_SOC=yes EMULATOR=$DATA/emulator.bin VMLINUX=$DATA/vmlinux.bin DTB=$DATA/rv32.dtb RAMDISK=$DATA/rootfs.cpio TRACE=no FLOW_INFO=no
make clean run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=no SUPERVISOR=yes CSR=yes COMPRESSED=no MUL=yes DIV=yes LRSC=yes AMO=yes MMU=yes REDO=1 TRACE=no LINUX_REGRESSION=yes
qemu-system-riscv32 -nographic -machine virt -m 1536M -device loader,file=$DATA/emulator.bin,addr=0x80000000,cpu-num=0 -device loader,file=$DATA/rv32.dtb,addr=0xC3000000 -device loader,file=$DATA/vmlinux.bin,addr=0xC0000000 -device loader,file=$DATA/rootfs.cpio,addr=0xc2000000
make run IBUS=CACHED DBUS=CACHED DEBUG_PLUGIN=STD DHRYSTONE=yess SUPERVISOR=yes CSR=yes COMPRESSED=yes MUL=yes DIV=yes LRSC=yes AMO=yes REDO=1 TRACE=no LINUX_REGRESSION=yes
program ../../../main/c/emulator/build/emulator.bin 0x80000000 verify
soc.loadBin(EMULATOR, 0x80000000);
Expand Down Expand Up @@ -149,12 +151,12 @@ object LinuxGen {
new IBusCachedPlugin(
resetVector = 0x80000000l,
compressedGen = false,
prediction = DYNAMIC_TARGET,
prediction = NONE,
injectorStage = false,
config = InstructionCacheConfig(
cacheSize = 4096*4,
cacheSize = 4096*1,
bytePerLine = 32,
wayCount = 4,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
Expand Down Expand Up @@ -184,9 +186,9 @@ object LinuxGen {
dBusCmdSlavePipe = true,
dBusRspSlavePipe = true,
config = new DataCacheConfig(
cacheSize = 4096*4,
cacheSize = 4096*1,
bytePerLine = 32,
wayCount = 4,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
Expand Down
5 changes: 5 additions & 0 deletions src/main/scala/vexriscv/demo/MuraxUtiles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,8 @@ class MuraxApb3Timer extends Component{
interruptCtrl.io.inputs(1) := timerB.io.full
io.interrupt := interruptCtrl.io.pendings.orR
}


object MuraxApb3TimerGen extends App{
SpinalVhdl(new MuraxApb3Timer())
}
8 changes: 4 additions & 4 deletions src/main/scala/vexriscv/plugin/CsrPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,8 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
interface
}

var exceptionPending : Bool = null
override def isExceptionPending(): Bool = exceptionPending
var exceptionPendings : Vec[Bool] = null
override def isExceptionPending(stage : Stage): Bool = exceptionPendings(pipeline.stages.indexOf(stage))

var jumpInterface : Flow[UInt] = null
var timerInterrupt, externalInterrupt, softwareInterrupt : Bool = null
Expand Down Expand Up @@ -420,7 +420,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
jumpInterface.valid := False
jumpInterface.payload.assignDontCare()

exceptionPending = False
exceptionPendings = Vec(Bool, pipeline.stages.length)
timerInterrupt = in Bool() setName("timerInterrupt")
externalInterrupt = in Bool() setName("externalInterrupt")
softwareInterrupt = in Bool() setName("softwareInterrupt") default(False)
Expand Down Expand Up @@ -721,7 +721,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception

//Avoid the PC register of the last stage to change durring an exception handleing (Used to fill Xepc)
stages.last.dontSample.getOrElseUpdate(PC, ArrayBuffer[Bool]()) += exceptionValids.last
exceptionPending setWhen(exceptionValidsRegs.orR)
exceptionPendings := exceptionValidsRegs
} else null


Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/vexriscv/plugin/DBusCachedPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,8 @@ class DBusCachedPlugin(config : DataCacheConfig,
val forceDatapath = False
when(dBusAccess.cmd.valid){
decode.arbitration.haltByOther := True
when(!stagesFromExecute.map(_.arbitration.isValid).orR && !pipeline.service(classOf[ExceptionService]).isExceptionPending()){
val exceptionService = pipeline.service(classOf[ExceptionService])
when(!stagesFromExecute.map(s => s.arbitration.isValid || exceptionService.isExceptionPending(s)).orR){
when(!cache.io.cpu.redo) {
cache.io.cpu.execute.isValid := True
dBusAccess.cmd.ready := !execute.arbitration.isStuck
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/vexriscv/plugin/DecoderSimplePlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
}
}

val defaults = mutable.HashMap[Stageable[_ <: BaseType], BaseType]()
val encodings = mutable.HashMap[MaskedLiteral,ArrayBuffer[(Stageable[_ <: BaseType], BaseType)]]()
val defaults = mutable.LinkedHashMap[Stageable[_ <: BaseType], BaseType]()
val encodings = mutable.LinkedHashMap[MaskedLiteral,ArrayBuffer[(Stageable[_ <: BaseType], BaseType)]]()
var decodeExceptionPort : Flow[ExceptionCause] = null


Expand Down Expand Up @@ -105,7 +105,7 @@ class DecoderSimplePlugin(catchIllegalInstruction : Boolean = false, forceLegalI
} else {
var offset = 0
var defaultValue, defaultCare = BigInt(0)
val offsetOf = mutable.HashMap[Stageable[_ <: BaseType], Int]()
val offsetOf = mutable.LinkedHashMap[Stageable[_ <: BaseType], Int]()

//Build defaults value and field offset map
stageables.foreach(e => {
Expand Down Expand Up @@ -191,8 +191,8 @@ object DecodingBench extends App{


object Symplify{
val cache = mutable.HashMap[Bits,mutable.HashMap[Masked,Bool]]()
def getCache(addr : Bits) = cache.getOrElseUpdate(addr,mutable.HashMap[Masked,Bool]())
val cache = mutable.LinkedHashMap[Bits,mutable.LinkedHashMap[Masked,Bool]]()
def getCache(addr : Bits) = cache.getOrElseUpdate(addr,mutable.LinkedHashMap[Masked,Bool]())

//Generate terms logic for the given input
def logicOf(input : Bits,terms : Seq[Masked]) = terms.map(t => getCache(input).getOrElseUpdate(t,t === input)).asBits.orR
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/vexriscv/plugin/HaltOnExceptionPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class HaltOnExceptionPlugin() extends Plugin[VexRiscv] with ExceptionService {
exceptionPortsInfos += ExceptionPortInfo(interface,stage,priority)
interface
}
override def isExceptionPending(): Bool = False
override def isExceptionPending(stage : Stage): Bool = False


override def build(pipeline: VexRiscv): Unit = {
Expand Down
20 changes: 12 additions & 8 deletions src/main/scala/vexriscv/plugin/IBusSimplePlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -220,17 +220,18 @@ class IBusSimplePlugin(resetVector : BigInt,

pipeline plug new FetchArea(pipeline) {
var cmd = Stream(IBusSimpleCmd())
iBus.cmd << (if(cmdForkPersistence && !cmdForkOnSecondStage) cmd.s2mPipe() else cmd)
val cmdWithS2mPipe = cmdForkPersistence && (!cmdForkOnSecondStage || mmuBus != null)
iBus.cmd << (if(cmdWithS2mPipe) cmd.s2mPipe() else cmd)

//Avoid sending to many iBus cmd
val pendingCmd = Reg(UInt(log2Up(pendingMax + 1) bits)) init (0)
val pendingCmdNext = pendingCmd + cmd.fire.asUInt - iBus.rsp.fire.asUInt
pendingCmd := pendingCmdNext

def cmdForkStage = if(!cmdForkPersistence || !cmdForkOnSecondStage) iBusRsp.stages(if(cmdForkOnSecondStage) 1 else 0) else iBusRsp.stages(1)
val secondStagePersistence = cmdForkPersistence && cmdForkOnSecondStage && !cmdWithS2mPipe
def cmdForkStage = if(!secondStagePersistence) iBusRsp.stages(if(cmdForkOnSecondStage) 1 else 0) else iBusRsp.stages(1)


val cmdFork = if(!cmdForkPersistence || !cmdForkOnSecondStage) new Area {
val cmdFork = if(!secondStagePersistence) new Area {
//This implementation keep the cmd on the bus until it's executed or the the pipeline is flushed
def stage = cmdForkStage
stage.halt setWhen(stage.input.valid && (!cmd.valid || !cmd.ready))
Expand All @@ -255,7 +256,7 @@ class IBusSimplePlugin(resetVector : BigInt,
mmuBus.cmd.isValid := cmdForkStage.input.valid
mmuBus.cmd.virtualAddress := cmdForkStage.input.payload
mmuBus.cmd.bypassTranslation := False
mmuBus.end := !cmdForkStage.output.fire || flush
mmuBus.end := cmdForkStage.output.fire || flush

cmd.pc := mmuBus.rsp.physicalAddress(31 downto 2) @@ "00"

Expand All @@ -265,7 +266,10 @@ class IBusSimplePlugin(resetVector : BigInt,
cmd.valid := False
}

cmdForkStage.halt.setWhen(mmuBus.busy)
when(mmuBus.busy){
cmdForkStage.input.valid := False
cmdForkStage.input.ready := False
}

val joinCtx = stageXToIBusRsp(cmdForkStage, mmuBus.rsp)
}
Expand All @@ -280,7 +284,7 @@ class IBusSimplePlugin(resetVector : BigInt,
val discardCounter = Reg(UInt(log2Up(pendingMax + 1) bits)) init (0)
discardCounter := discardCounter - (iBus.rsp.fire && discardCounter =/= 0).asUInt
when(flush) {
if(cmdForkOnSecondStage && cmdForkPersistence)
if(secondStagePersistence)
discardCounter := pendingCmd + cmd.valid.asUInt - iBus.rsp.fire.asUInt
else
discardCounter := (if(cmdForkOnSecondStage) pendingCmdNext else pendingCmd - iBus.rsp.fire.asUInt)
Expand Down Expand Up @@ -318,7 +322,7 @@ class IBusSimplePlugin(resetVector : BigInt,
if(memoryTranslatorPortConfig != null){
redoRequired setWhen( stages.last.input.valid && mmu.joinCtx.refilling)
redoBranch.valid := redoRequired && iBusRsp.readyForError
redoBranch.payload := stages.last.input.payload
redoBranch.payload := decode.input(PC)
decode.arbitration.flushAll setWhen(redoBranch.valid)
}

Expand Down
3 changes: 0 additions & 3 deletions src/main/scala/vexriscv/plugin/MmuPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ class MmuPlugin(ioRange : UInt => Bool,
}

val shared = new Area {
val busy = Reg(Bool) init(False)

val State = new SpinalEnum{
val IDLE, L1_CMD, L1_RSP, L0_CMD, L0_RSP = newElement()
}
Expand Down Expand Up @@ -182,7 +180,6 @@ class MmuPlugin(ioRange : UInt => Bool,
is(State.IDLE){
for(port <- portsInfo.sortBy(_.priority)){
when(port.bus.cmd.isValid && port.bus.rsp.refilling){
busy := True
vpn(1) := port.bus.cmd.virtualAddress(31 downto 22)
vpn(0) := port.bus.cmd.virtualAddress(21 downto 12)
portId := port.id
Expand Down
Loading

0 comments on commit e47b76f

Please sign in to comment.