mirror of
https://github.com/SpinalHDL/VexRiscv.git
synced 2025-04-24 05:57:07 -04:00
Now able to catch missaligned instruction/data addresses
Modify arbitration with an flushAll + isFlushed
This commit is contained in:
parent
4000191966
commit
c5520656e5
22 changed files with 77430 additions and 3651 deletions
|
@ -94,7 +94,7 @@ trait Pipeline {
|
|||
inputDefault := stage.inserts(key)
|
||||
} else {
|
||||
val stageBefore = stages(stageIndex - 1)
|
||||
inputDefault := RegNextWhen(stageBefore.output(key), !stage.arbitration.isStuck || stage.arbitration.removeIt)
|
||||
inputDefault := RegNextWhen(stageBefore.output(key), !stage.arbitration.isStuck)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,8 +102,9 @@ trait Pipeline {
|
|||
|
||||
//Arbitration
|
||||
for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)) {
|
||||
stage.arbitration.isFlushed := stages.drop(stageIndex).map(_.arbitration.flushAll).orR
|
||||
if(!unremovableStages.contains(stage))
|
||||
stage.arbitration.removeIt setWhen stages.drop(stageIndex).map(_.arbitration.flushIt).orR
|
||||
stage.arbitration.removeIt setWhen stage.arbitration.isFlushed
|
||||
else
|
||||
assert(stage.arbitration.removeIt === False,"removeIt should never be asserted on this stage")
|
||||
|
||||
|
|
|
@ -10,7 +10,11 @@ object NONE extends BranchPrediction
|
|||
object STATIC extends BranchPrediction
|
||||
object DYNAMIC extends BranchPrediction
|
||||
|
||||
class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRamSizeLog2 : Int = 10,historyWidth : Int = 2) extends Plugin[VexRiscv]{
|
||||
class BranchPlugin(earlyBranch : Boolean,
|
||||
unalignedExceptionGen : Boolean,
|
||||
prediction : BranchPrediction,
|
||||
historyRamSizeLog2 : Int = 10,
|
||||
historyWidth : Int = 2) extends Plugin[VexRiscv]{
|
||||
object BranchCtrlEnum extends SpinalEnum(binarySequential){
|
||||
val INC,B,JAL,JALR = newElement()
|
||||
}
|
||||
|
@ -22,6 +26,8 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
|
||||
var jumpInterface : Flow[UInt] = null
|
||||
var predictionJumpInterface : Flow[UInt] = null
|
||||
var predictionExceptionPort : Flow[ExceptionCause] = null
|
||||
var branchExceptionPort : Flow[ExceptionCause] = null
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import Riscv._
|
||||
|
@ -50,19 +56,27 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
|
||||
decoderService.addDefault(BRANCH_CTRL, BranchCtrlEnum.INC)
|
||||
decoderService.add(List(
|
||||
JAL -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JAL , ALU_CTRL -> AluCtrlEnum.ADD_SUB)),
|
||||
JAL -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JAL, ALU_CTRL -> AluCtrlEnum.ADD_SUB)),
|
||||
JALR -> (jActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.JALR, ALU_CTRL -> AluCtrlEnum.ADD_SUB, REG1_USE -> True)),
|
||||
BEQ -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)),
|
||||
BNE -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)),
|
||||
BLT -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> False)),
|
||||
BGE -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> False)),
|
||||
BEQ -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)),
|
||||
BNE -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B)),
|
||||
BLT -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> False)),
|
||||
BGE -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> False)),
|
||||
BLTU -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> True)),
|
||||
BGEU -> (bActions ++ List(BRANCH_CTRL -> BranchCtrlEnum.B, SRC_LESS_UNSIGNED -> True))
|
||||
))
|
||||
|
||||
val pcManagerService = pipeline.service(classOf[JumpService])
|
||||
val pcManagerService = pipeline.service(classOf[JumpService])
|
||||
jumpInterface = pcManagerService.createJumpInterface(pipeline.execute)
|
||||
if(prediction != NONE) predictionJumpInterface = pcManagerService.createJumpInterface(pipeline.decode)
|
||||
if (prediction != NONE)
|
||||
predictionJumpInterface = pcManagerService.createJumpInterface(pipeline.decode)
|
||||
|
||||
if (unalignedExceptionGen) {
|
||||
val exceptionService = pipeline.service(classOf[ExceptionService])
|
||||
branchExceptionPort = exceptionService.newExceptionPort(if (earlyBranch) pipeline.execute else pipeline.memory)
|
||||
if (prediction != NONE)
|
||||
predictionExceptionPort = exceptionService.newExceptionPort(pipeline.decode)
|
||||
}
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = prediction match {
|
||||
|
@ -112,7 +126,12 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
jumpInterface.payload := input(BRANCH_CALC)
|
||||
|
||||
when(jumpInterface.valid) {
|
||||
stages(indexOf(branchStage) - 1).arbitration.flushIt := True
|
||||
stages(indexOf(branchStage) - 1).arbitration.flushAll := True
|
||||
}
|
||||
|
||||
if(unalignedExceptionGen) {
|
||||
branchExceptionPort.valid := arbitration.isValid && input(BRANCH_DO) && jumpInterface.payload(1 downto 0) =/= 0
|
||||
branchExceptionPort.code := 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +176,12 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
predictionJumpInterface.valid := input(PREDICTION_HAD_BRANCHED) && arbitration.isFiring //TODO OH Doublon de priorité
|
||||
predictionJumpInterface.payload := input(PC) + ((input(BRANCH_CTRL) === BranchCtrlEnum.JAL) ? imm.j_sext | imm.b_sext).asUInt
|
||||
when(predictionJumpInterface.valid) {
|
||||
fetch.arbitration.flushIt := True
|
||||
fetch.arbitration.flushAll := True
|
||||
}
|
||||
|
||||
if(unalignedExceptionGen) {
|
||||
predictionExceptionPort.valid := input(PREDICTION_HAD_BRANCHED) && arbitration.isValid && predictionJumpInterface.payload(1 downto 0) =/= 0
|
||||
predictionExceptionPort.code := 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,7 +231,12 @@ class BranchPlugin(earlyBranch : Boolean,prediction : BranchPrediction,historyRa
|
|||
jumpInterface.payload := input(BRANCH_CALC)
|
||||
|
||||
when(jumpInterface.valid) {
|
||||
stages(indexOf(branchStage) - 1).arbitration.flushIt := True
|
||||
stages(indexOf(branchStage) - 1).arbitration.flushAll := True
|
||||
}
|
||||
|
||||
if(unalignedExceptionGen) {
|
||||
branchExceptionPort.valid := arbitration.isValid && input(BRANCH_DO) && jumpInterface.payload(1 downto 0) =/= 0
|
||||
branchExceptionPort.code := 0
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ case class DBusSimpleRsp() extends Bundle{
|
|||
val data = Bits(32 bit)
|
||||
}
|
||||
|
||||
class DBusSimplePlugin extends Plugin[VexRiscv]{
|
||||
class DBusSimplePlugin(unalignedExceptionGen : Boolean) extends Plugin[VexRiscv]{
|
||||
|
||||
var dCmd : Stream[DBusSimpleCmd] = null
|
||||
var dRsp : DBusSimpleRsp = null
|
||||
|
@ -30,7 +30,7 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
object MEMORY_READ_DATA extends Stageable(Bits(32 bits))
|
||||
object MEMORY_ADDRESS_LOW extends Stageable(UInt(2 bits))
|
||||
|
||||
|
||||
var executeExceptionPort : Flow[ExceptionCause] = null
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import Riscv._
|
||||
|
@ -71,9 +71,10 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
SW -> (storeActions)
|
||||
))
|
||||
|
||||
|
||||
// val exceptionService = pipeline.service(classOf[ExceptionService])
|
||||
// executeExceptionPort = exceptionService.newExceptionPort(pipeline.execute)
|
||||
if(unalignedExceptionGen) {
|
||||
val exceptionService = pipeline.service(classOf[ExceptionService])
|
||||
executeExceptionPort = exceptionService.newExceptionPort(pipeline.execute)
|
||||
}
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
|
@ -99,6 +100,12 @@ class DBusSimplePlugin extends Plugin[VexRiscv]{
|
|||
}
|
||||
|
||||
insert(MEMORY_ADDRESS_LOW) := dCmd.address(1 downto 0)
|
||||
|
||||
if(unalignedExceptionGen){
|
||||
executeExceptionPort.code := (dCmd.wr ? U(6) | U(4)).resized
|
||||
executeExceptionPort.valid := (arbitration.isValid && input(MEMORY_ENABLE)
|
||||
&& ((dCmd.size === 2 && dCmd.address(1 downto 0) =/= 0) || (dCmd.size === 1 && dCmd.address(0 downto 0) =/= 0)))
|
||||
}
|
||||
}
|
||||
|
||||
//Collect dRsp read responses
|
||||
|
|
|
@ -17,6 +17,10 @@ class IBusSimplePlugin(interfaceKeepData : Boolean) extends Plugin[VexRiscv]{
|
|||
var iCmd : Stream[IBusSimpleCmd] = null
|
||||
var iRsp : IBusSimpleRsp = null
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
pipeline.unremovableStages += pipeline.prefetch
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
|
|
@ -89,9 +89,9 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
}
|
||||
|
||||
object ENV_CTRL extends Stageable(EnvCtrlEnum())
|
||||
object EXCEPTION extends Stageable(Bool)
|
||||
// object EXCEPTION extends Stageable(Bool)
|
||||
object IS_CSR extends Stageable(Bool)
|
||||
object EXCEPTION_CAUSE extends Stageable(ExceptionCause())
|
||||
// object EXCEPTION_CAUSE extends Stageable(ExceptionCause())
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
|
@ -241,8 +241,12 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
//Aggregate all exception port and remove required instructions
|
||||
val exceptionPortCtrl = if(exceptionPortsInfos.nonEmpty) new Area{
|
||||
val firstStageIndexWithExceptionPort = exceptionPortsInfos.map(i => indexOf(i.stage)).min
|
||||
val pipelineHasException = stages.drop(firstStageIndexWithExceptionPort).map(s => s.arbitration.isValid && s.input(EXCEPTION)).orR
|
||||
decode.arbitration.haltIt setWhen(pipelineHasException)
|
||||
val exceptionValids = Vec(Bool,stages.length)
|
||||
val exceptionValidsRegs = Vec(Reg(Bool) init(False), stages.length)
|
||||
val exceptionContext = Reg(ExceptionCause())
|
||||
val pipelineHasException = exceptionValids.orR
|
||||
|
||||
pipelineLiberator.enable setWhen(pipelineHasException)
|
||||
|
||||
val groupedByStage = exceptionPortsInfos.map(_.stage).distinct.map(s => {
|
||||
assert(s != writeBack)
|
||||
|
@ -260,27 +264,40 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
}
|
||||
ExceptionPortInfo(stagePort,s)
|
||||
})
|
||||
val sortedByStage = groupedByStage.sortWith((a, b) => pipeline.indexOf(a.stage) > pipeline.indexOf(b.stage))
|
||||
|
||||
sortedByStage.head.stage.insert(EXCEPTION) := False
|
||||
sortedByStage.head.stage.insert(EXCEPTION_CAUSE).assignDontCare()
|
||||
for(portInfo <- sortedByStage; port = portInfo.port ; stage = portInfo.stage){
|
||||
when(port.valid){
|
||||
stages(indexOf(stage) - 1).arbitration.flushIt := True
|
||||
stage.input(EXCEPTION) := True
|
||||
stage.input(EXCEPTION_CAUSE) := port.payload
|
||||
val sortedByStage = groupedByStage.sortWith((a, b) => pipeline.indexOf(a.stage) < pipeline.indexOf(b.stage))
|
||||
|
||||
exceptionValids := exceptionValidsRegs
|
||||
for(portInfo <- sortedByStage; port = portInfo.port ; stage = portInfo.stage; stageId = indexOf(portInfo.stage)) {
|
||||
when(port.valid) {
|
||||
stages(indexOf(stage) - 1).arbitration.flushAll := True
|
||||
stage.arbitration.removeIt := True
|
||||
exceptionValids(stageId) := True
|
||||
exceptionContext := port.payload
|
||||
}
|
||||
}
|
||||
for(stageId <- firstStageIndexWithExceptionPort until stages.length; stage = stages(stageId) ){
|
||||
when(stage.arbitration.isFlushed){
|
||||
exceptionValids(stageId) := False
|
||||
}
|
||||
when(!stage.arbitration.isStuck){
|
||||
exceptionValidsRegs(stageId) := (if(stageId != firstStageIndexWithExceptionPort) exceptionValids(stageId-1) else False)
|
||||
}otherwise{
|
||||
exceptionValidsRegs(stageId) := exceptionValids(stageId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else null
|
||||
|
||||
|
||||
|
||||
val interrupt = ((mip.MSIP && mie.MSIE) || (mip.MEIP && mie.MEIE) || (mip.MTIP && mie.MTIE)) && mstatus.MIE
|
||||
val exception = if(exceptionPortsInfos.nonEmpty) writeBack.arbitration.isValid && writeBack.input(EXCEPTION) else False
|
||||
val exception = if(exceptionPortCtrl != null) exceptionPortCtrl.exceptionValids.last else False
|
||||
val writeBackWfi = if(wfiGen) writeBack.arbitration.isValid && writeBack.input(ENV_CTRL) === EnvCtrlEnum.WFI else False
|
||||
|
||||
//Interrupt/Exception entry logic
|
||||
pipelineLiberator.enable setWhen interrupt
|
||||
pipelineLiberator.enable setWhen(interrupt)
|
||||
when(exception || (interrupt && pipelineLiberator.done)){
|
||||
jumpInterface.valid := True
|
||||
jumpInterface.payload := mtvec
|
||||
|
@ -294,7 +311,7 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
mcause.interrupt := interrupt
|
||||
mcause.exceptionCode := interrupt.mux(
|
||||
True -> ((mip.MEIP && mie.MEIE) ? U(11) | ((mip.MSIP && mie.MSIE) ? U(3) | U(7))),
|
||||
False -> (if(exceptionPortCtrl != null) writeBack.input(EXCEPTION_CAUSE).exceptionCode else U(0))
|
||||
False -> (if(exceptionPortCtrl != null) exceptionPortCtrl.exceptionContext.code else U(0))
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -303,21 +320,21 @@ class MachineCsr(config : MachineCsrConfig) extends Plugin[VexRiscv] with Except
|
|||
when(memory.arbitration.isFiring && memory.input(ENV_CTRL) === EnvCtrlEnum.MRET){
|
||||
jumpInterface.valid := True
|
||||
jumpInterface.payload := mepc
|
||||
execute.arbitration.flushIt := True
|
||||
execute.arbitration.flushAll := True
|
||||
mstatus.MIE := mstatus.MPIE
|
||||
}
|
||||
|
||||
//Manage ECALL instructions
|
||||
if(ecallGen) when(execute.arbitration.isValid && execute.input(ENV_CTRL) === EnvCtrlEnum.ECALL){
|
||||
pluginExceptionPort.valid := True
|
||||
pluginExceptionPort.exceptionCode := 11
|
||||
pluginExceptionPort.code := 11
|
||||
}
|
||||
|
||||
//Manage WFI instructions
|
||||
if(wfiGen) when(execute.arbitration.isValid && execute.input(ENV_CTRL) === EnvCtrlEnum.WFI){
|
||||
when(!interrupt){
|
||||
execute.arbitration.haltIt := True
|
||||
decode.arbitration.flushIt := True
|
||||
decode.arbitration.flushAll := True
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package SpinalRiscv.Plugin
|
||||
|
||||
import SpinalRiscv.{JumpService, Stage, VexRiscv}
|
||||
import SpinalRiscv._
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
class PcManagerSimplePlugin(resetVector : BigInt,fastPcCalculation : Boolean) extends Plugin[VexRiscv] with JumpService{
|
||||
class PcManagerSimplePlugin(resetVector : BigInt, fastPcCalculation : Boolean) extends Plugin[VexRiscv] with JumpService{
|
||||
|
||||
|
||||
//FetchService interface
|
||||
|
@ -17,7 +17,8 @@ class PcManagerSimplePlugin(resetVector : BigInt,fastPcCalculation : Boolean) ex
|
|||
jumpInfos += JumpInfo(interface,stage)
|
||||
interface
|
||||
}
|
||||
|
||||
var prefetchExceptionPort : Flow[ExceptionCause] = null
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
pipeline.unremovableStages += pipeline.prefetch
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ trait RegFileReadKind
|
|||
object ASYNC extends RegFileReadKind
|
||||
object SYNC extends RegFileReadKind
|
||||
|
||||
class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]{
|
||||
class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = false) extends Plugin[VexRiscv]{
|
||||
import Riscv._
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
|
@ -25,6 +25,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind) extends Plugin[VexRiscv]
|
|||
|
||||
val global = pipeline plug new Area{
|
||||
val regFile = Mem(Bits(32 bits),32) addAttribute("verilator public")
|
||||
if(zeroBoot) regFile.init(List.fill(32)(B(0, 32 bits)))
|
||||
}
|
||||
|
||||
//Read register file
|
||||
|
|
|
@ -14,7 +14,7 @@ trait DecoderService{
|
|||
}
|
||||
|
||||
case class ExceptionCause() extends Bundle{
|
||||
val exceptionCode = UInt(4 bits)
|
||||
val code = UInt(4 bits)
|
||||
}
|
||||
|
||||
trait ExceptionService{
|
||||
|
|
|
@ -47,9 +47,10 @@ class Stage() extends Area{
|
|||
val arbitration = new Area{
|
||||
val haltIt = False
|
||||
val removeIt = False
|
||||
val flushIt = False
|
||||
val flushAll = False
|
||||
val isValid = RegInit(False)
|
||||
val isStuck = Bool
|
||||
val isFlushed = Bool
|
||||
val isStuckByOthers = Bool
|
||||
val isFiring = Bool
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@ object TopLevel {
|
|||
mbadaddrAccess = CsrAccess.READ_WRITE,
|
||||
mcycleAccess = CsrAccess.READ_WRITE,
|
||||
minstretAccess = CsrAccess.READ_WRITE,
|
||||
ecallGen = false,
|
||||
wfiGen = false
|
||||
ecallGen = true,
|
||||
wfiGen = true
|
||||
)
|
||||
|
||||
// val csrConfig = MachineCsrConfig(
|
||||
|
@ -69,30 +69,35 @@ object TopLevel {
|
|||
|
||||
config.plugins ++= List(
|
||||
new PcManagerSimplePlugin(0x00000000l, false),
|
||||
new IBusSimplePlugin(true),
|
||||
new IBusSimplePlugin(
|
||||
interfaceKeepData = true
|
||||
),
|
||||
new DecoderSimplePlugin,
|
||||
new RegFilePlugin(Plugin.SYNC),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = Plugin.SYNC,
|
||||
zeroBoot = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin,
|
||||
new FullBarrielShifterPlugin,
|
||||
// new LightShifterPlugin,
|
||||
new DBusSimplePlugin,
|
||||
// new HazardSimplePlugin(false, true, false, true),
|
||||
new DBusSimplePlugin(
|
||||
unalignedExceptionGen = true
|
||||
),
|
||||
new HazardSimplePlugin(true, true, true, true),
|
||||
// new HazardSimplePlugin(false, true, false, true),
|
||||
// new HazardSimplePlugin(false, false, false, false),
|
||||
new MulPlugin,
|
||||
new DivPlugin,
|
||||
new MachineCsr(csrConfig),
|
||||
new BranchPlugin(false, DYNAMIC)
|
||||
new BranchPlugin(
|
||||
earlyBranch = false,
|
||||
unalignedExceptionGen = true,
|
||||
prediction = DYNAMIC
|
||||
)
|
||||
)
|
||||
|
||||
val toplevel = new VexRiscv(config)
|
||||
|
||||
|
||||
|
||||
// toplevel.service(classOf[DecoderSimplePlugin]).bench(toplevel)
|
||||
|
||||
|
||||
toplevel
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ Arr_1_Glob[8]: 7
|
|||
Arr_2_Glob[8][7]: 210
|
||||
should be: Number_Of_Runs + 10
|
||||
Ptr_Glob->
|
||||
Ptr_Comp: 1073809016
|
||||
Ptr_Comp: 1073810920
|
||||
should be: (implementation-dependent)
|
||||
Discr: 0
|
||||
should be: 0
|
||||
|
@ -33,7 +33,7 @@ Ptr_Glob->
|
|||
Str_Comp: DHRYSTONE PROGRAM, SOME STRING
|
||||
should be: DHRYSTONE PROGRAM, SOME STRING
|
||||
Next_Ptr_Glob->
|
||||
Ptr_Comp: 1073809016
|
||||
Ptr_Comp: 1073810920
|
||||
should be: (implementation-dependent), same as above
|
||||
Discr: 0
|
||||
should be: 0
|
||||
|
|
9194
src/test/cpp/testA/dhrystoneO3.memRef
Normal file
9194
src/test/cpp/testA/dhrystoneO3.memRef
Normal file
File diff suppressed because it is too large
Load diff
10354
src/test/cpp/testA/dhrystoneO3.memWrong
Normal file
10354
src/test/cpp/testA/dhrystoneO3.memWrong
Normal file
File diff suppressed because it is too large
Load diff
15347
src/test/cpp/testA/dhrystoneO3.regRef
Normal file
15347
src/test/cpp/testA/dhrystoneO3.regRef
Normal file
File diff suppressed because it is too large
Load diff
10858
src/test/cpp/testA/dhrystoneO3.regWrong
Normal file
10858
src/test/cpp/testA/dhrystoneO3.regWrong
Normal file
File diff suppressed because it is too large
Load diff
45
src/test/cpp/testA/fail.gtkw
Normal file
45
src/test/cpp/testA/fail.gtkw
Normal file
|
@ -0,0 +1,45 @@
|
|||
[*]
|
||||
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
|
||||
[*] Sat Mar 25 22:06:00 2017
|
||||
[*]
|
||||
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/dhrystoneO3.vcd"
|
||||
[dumpfile_mtime] "Sat Mar 25 22:05:31 2017"
|
||||
[dumpfile_size] 414222144
|
||||
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/fail.gtkw"
|
||||
[timestart] 60961
|
||||
[size] 1000 600
|
||||
[pos] -1 -1
|
||||
*-7.000000 61271 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[treeopen] TOP.
|
||||
[sst_width] 201
|
||||
[signals_width] 571
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 155
|
||||
@28
|
||||
TOP.VexRiscv.decode_EXCEPTION
|
||||
TOP.VexRiscv.execute_EXCEPTION
|
||||
TOP.VexRiscv.memory_EXCEPTION
|
||||
TOP.VexRiscv.writeBack_EXCEPTION
|
||||
TOP.VexRiscv.execute_arbitration_isValid
|
||||
TOP.VexRiscv.execute_MEMORY_ENABLE
|
||||
@22
|
||||
TOP.VexRiscv.execute_PC[31:0]
|
||||
TOP.VexRiscv.RegFilePlugin_regFile(8)[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.writeBack_arbitration_isValid
|
||||
@23
|
||||
TOP.VexRiscv.writeBack_PC[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_valid
|
||||
@22
|
||||
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_address[4:0]
|
||||
TOP.VexRiscv.writeBack_RegFilePlugin_regFileWrite_payload_data[31:0]
|
||||
TOP.VexRiscv.dCmd_payload_address[31:0]
|
||||
TOP.VexRiscv.dCmd_payload_data[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.dCmd_payload_size[1:0]
|
||||
TOP.VexRiscv.dCmd_payload_wr
|
||||
TOP.VexRiscv.dCmd_ready
|
||||
TOP.VexRiscv.dCmd_valid
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
|
@ -1,5 +1,8 @@
|
|||
#include "VVexRiscv.h"
|
||||
#include "VVexRiscv_VexRiscv.h"
|
||||
#ifdef REF
|
||||
#include "VVexRiscv_RiscvCore.h"
|
||||
#endif
|
||||
#include "verilated.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
#include <stdio.h>
|
||||
|
@ -214,7 +217,12 @@ public:
|
|||
top->clk = 1;
|
||||
|
||||
postReset();
|
||||
|
||||
#ifdef REF
|
||||
if(bootPc != -1) top->VexRiscv->core->prefetch_pc = bootPc;
|
||||
#else
|
||||
if(bootPc != -1) top->VexRiscv->prefetch_PcManagerSimplePlugin_pcReg = bootPc;
|
||||
#endif
|
||||
|
||||
try {
|
||||
// run simulation for 100 clock periods
|
||||
|
@ -245,11 +253,15 @@ public:
|
|||
|
||||
uint32_t addr = top->dCmd_payload_address;
|
||||
if(top->dCmd_payload_wr){
|
||||
memTraces << (currentTime
|
||||
memTraces <<
|
||||
#ifdef TRACE_WITH_TIME
|
||||
(currentTime
|
||||
#ifdef REF
|
||||
-2
|
||||
#endif
|
||||
) << " : WRITE mem" << (1 << top->dCmd_payload_size) << "[" << addr << "] = " << top->dCmd_payload_data << endl;
|
||||
) <<
|
||||
#endif
|
||||
" : WRITE mem" << (1 << top->dCmd_payload_size) << "[" << addr << "] = " << top->dCmd_payload_data << endl;
|
||||
for(uint32_t b = 0;b < (1 << top->dCmd_payload_size);b++){
|
||||
uint32_t offset = (addr+b)&0x3;
|
||||
*mem.get(addr + b) = top->dCmd_payload_data >> (offset*8);
|
||||
|
@ -280,11 +292,15 @@ public:
|
|||
case 0xF00FFF48u: dRsp_inst_next = mTimeCmp; break;
|
||||
case 0xF00FFF4Cu: dRsp_inst_next = mTimeCmp >> 32; break;
|
||||
}
|
||||
memTraces << (currentTime
|
||||
memTraces <<
|
||||
#ifdef TRACE_WITH_TIME
|
||||
(currentTime
|
||||
#ifdef REF
|
||||
-2
|
||||
#endif
|
||||
) << " : READ mem" << (1 << top->dCmd_payload_size) << "[" << addr << "] = " << dRsp_inst_next << endl;
|
||||
#endif
|
||||
) <<
|
||||
#endif
|
||||
" : READ mem" << (1 << top->dCmd_payload_size) << "[" << addr << "] = " << dRsp_inst_next << endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -303,7 +319,11 @@ public:
|
|||
if(iStall) top->iCmd_ready = VL_RANDOM_I(1);
|
||||
if(dStall) top->dCmd_ready = VL_RANDOM_I(1);
|
||||
if(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_valid == 1 && top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address != 0){
|
||||
regTraces << currentTime << " : reg[" << (uint32_t)top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address << "] = " << top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data << endl;
|
||||
regTraces <<
|
||||
#ifdef TRACE_WITH_TIME
|
||||
currentTime <<
|
||||
#endif
|
||||
" : reg[" << (uint32_t)top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address << "] = " << top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data << endl;
|
||||
}
|
||||
checks();
|
||||
}
|
||||
|
@ -413,7 +433,7 @@ public:
|
|||
}
|
||||
|
||||
virtual void checks(){
|
||||
if(top->VexRiscv->writeBack_arbitration_isValid == 1 && top->VexRiscv->writeBack_INSTRUCTION == 0x00000073){
|
||||
if(/*top->VexRiscv->writeBack_arbitration_isValid == 1 && */top->VexRiscv->writeBack_INSTRUCTION == 0x00000073){
|
||||
uint32_t code = top->VexRiscv->RegFilePlugin_regFile[28];
|
||||
if((code & 1) == 0){
|
||||
cout << "Wrong error code"<< endl;
|
||||
|
@ -564,15 +584,19 @@ int main(int argc, char **argv, char **env) {
|
|||
for(const string &name : riscvTestDiv){
|
||||
redo(REDO,RiscvTest(name).run();)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CSR
|
||||
uint32_t machineCsrRef[] = {1,11, 2,0x80000003u, 3,0x80000007u, 4,0x8000000bu, 5,6,7,0x80000007u ,8};
|
||||
uint32_t machineCsrRef[] = {1,11, 2,0x80000003u, 3,0x80000007u, 4,0x8000000bu, 5,6,7,0x80000007u ,
|
||||
8,6,9,6,10,4,11,4, 12,13,0,14};
|
||||
redo(REDO,TestX28("machineCsr",machineCsrRef, sizeof(machineCsrRef)/4).run(2e3);)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef DHRYSTONE
|
||||
Dhrystone("dhrystoneO3",true,true).run(1e6);
|
||||
// Dhrystone("dhrystoneO3",false,false).run(0.05e6);
|
||||
Dhrystone("dhrystoneO3",true,true).run(1.1e6);
|
||||
Dhrystone("dhrystoneO3M",true,true).run(0.8e6);
|
||||
Dhrystone("dhrystoneO3M",false,false).run(0.8e6);
|
||||
// Dhrystone("dhrystoneO3ML",false,false).run(8e6);
|
||||
|
@ -580,8 +604,8 @@ int main(int argc, char **argv, char **env) {
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef CSR
|
||||
redo(REDO,Workspace("freeRTOS_demo").loadHex("../../resources/hex/freeRTOS_demo.hex")->bootAt(0x80000000u)->run(100e6);)
|
||||
#ifdef FREE_RTOS
|
||||
redo(1,Workspace("freeRTOS_demo").loadHex("../../resources/hex/freeRTOS_demo.hex")->bootAt(0x80000000u)->run(100e6);)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,10 @@ TRACE=no
|
|||
TRACE_START=0
|
||||
CSR=yes
|
||||
DHRYSTONE=yes
|
||||
REDO=5
|
||||
FREE_RTOS=no
|
||||
REDO=10
|
||||
REF=no
|
||||
TRACE_WITH_TIME=no
|
||||
|
||||
ADDCFLAGS += -CFLAGS -DREDO=${REDO}
|
||||
ifeq ($(DHRYSTONE),yes)
|
||||
|
@ -18,7 +21,19 @@ ifeq ($(CSR),yes)
|
|||
ADDCFLAGS += -CFLAGS -DCSR
|
||||
endif
|
||||
|
||||
ifeq ($(TRACE_WITH_TIME),yes)
|
||||
ADDCFLAGS += -CFLAGS -DTRACE_WITH_TIME
|
||||
endif
|
||||
|
||||
ifeq ($(REF),yes)
|
||||
ADDCFLAGS += -CFLAGS -DREF
|
||||
endif
|
||||
|
||||
ADDCFLAGS += -CFLAGS -DTRACE_START=${TRACE_START}
|
||||
ifeq ($(FREE_RTOS),yes)
|
||||
ADDCFLAGS += -CFLAGS -DFREE_RTOS
|
||||
endif
|
||||
|
||||
|
||||
run: compile
|
||||
./obj_dir/VVexRiscv
|
||||
|
|
15219
src/test/resources/asm/dhrystoneO3.asm
Normal file
15219
src/test/resources/asm/dhrystoneO3.asm
Normal file
File diff suppressed because it is too large
Load diff
12531
src/test/resources/asm/machineCsr.asm
Normal file
12531
src/test/resources/asm/machineCsr.asm
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,24 +1,30 @@
|
|||
:100000006F00000713000000130000001300000041
|
||||
:100000006F0000091300000013000000130000003F
|
||||
:100010001300000013000000130000001300000094
|
||||
:10002000732E2034930EB0006398CE01F32E10345B
|
||||
:10003000938E4E0073901E34B70E0080938E3E0058
|
||||
:100040006396CE01930E800073B04E34B70E0080DD
|
||||
:10005000938E7E006394CE0173504030B70E0080C3
|
||||
:10006000938EBE006394CE017350403073002030F5
|
||||
:10007000130E100073000000130E20009302800086
|
||||
:1000800073A002309302800073904230930280008C
|
||||
:1000900073A042341300000013000000130000009E
|
||||
:1000A0001300000013000000130000001300000004
|
||||
:1000B00013000000130000001300000013000000F4
|
||||
:1000C00013000000130E30009302000873904230BA
|
||||
:10002000732E2034631E0E00130FC0FFF32E103406
|
||||
:10003000B3FEEE01938E4E0073901E346F00C0012C
|
||||
:10004000B70E0080337FDE0163180F00F32E1034EB
|
||||
:10005000938E4E0073901E34B70E0080938E3E0038
|
||||
:100060006396CE01930E800073B04E34B70E0080BD
|
||||
:10007000938E7E006394CE0173504030B70E0080A3
|
||||
:10008000938EBE006394CE017350403073002030D5
|
||||
:10009000130E100073000000130E20009302800066
|
||||
:1000A00073A002309302800073904230930280006C
|
||||
:1000B00073A042341300000013000000130000007E
|
||||
:1000C00013000000130000001300000013000000E4
|
||||
:1000D00013000000130000001300000013000000D4
|
||||
:1000E000130000001300000013000000130E400076
|
||||
:1000F000B712000093820280739042301300000018
|
||||
:1001000013000000130000001300000013000000A3
|
||||
:100110001300000013000000130E5000B70110F090
|
||||
:10012000938101F403A2010083A241001302F23F74
|
||||
:1001300023A4410023A65100130E600013020008FF
|
||||
:1001400073104230130E700073005010130E8000B5
|
||||
:1000E00013000000130E300093020008739042309A
|
||||
:1000F00013000000130000001300000013000000B4
|
||||
:10010000130000001300000013000000130E400055
|
||||
:10011000B7120000938202807390423013000000F7
|
||||
:100120001300000013000000130000001300000083
|
||||
:100130001300000013000000130E5000B70110F070
|
||||
:10014000938101F403A2010083A241001302F23F54
|
||||
:1001500023A4410023A65100130E600013020008DF
|
||||
:1001600073104230130E700073005010130E800095
|
||||
:100170009301100023A04100130E90002390410032
|
||||
:10018000130EA00003A20100130EB00003920100A1
|
||||
:10019000130EC000130ED000832000006F0020005B
|
||||
:0801A00083200000130EE000B3
|
||||
:020000044000BA
|
||||
:1000000013050000678000001305000067800000F2
|
||||
:1000100097020000678082FF1305000067800000E0
|
||||
|
@ -3192,5 +3198,5 @@
|
|||
:10C6100008C6004008C6004010C6004010C60040D2
|
||||
:10C6200018C6004018C6004080BD004080BD0040D4
|
||||
:10C6300001000000FFFFFFFF00000200C88900406A
|
||||
:040000030000007089
|
||||
:040000030000009069
|
||||
:00000001FF
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue