This commit is contained in:
Dolu1990 2018-06-25 09:36:07 +02:00
parent d73aa9ce00
commit ffe5fa23f0
7 changed files with 98 additions and 29 deletions

View File

@ -13,6 +13,7 @@ trait JumpService{
trait IBusFetcher{ trait IBusFetcher{
def haltIt() : Unit def haltIt() : Unit
def flushIt() : Unit
def incoming() : Bool def incoming() : Bool
def pcValid(stage : Stage) : Bool def pcValid(stage : Stage) : Bool
def getInjectionPort() : Stream[Bits] def getInjectionPort() : Stream[Bits]

View File

@ -33,14 +33,14 @@ object TestsWorkspace {
plugins = List( plugins = List(
new IBusSimplePlugin( new IBusSimplePlugin(
resetVector = 0x80000000l, resetVector = 0x80000000l,
relaxedPcCalculation = false, relaxedPcCalculation = true,
relaxedBusCmdValid = false, relaxedBusCmdValid = false,
prediction = NONE, prediction = DYNAMIC_TARGET,
historyRamSizeLog2 = 10, historyRamSizeLog2 = 10,
catchAccessFault = true, catchAccessFault = true,
compressedGen = false, compressedGen = true,
busLatencyMin = 1, busLatencyMin = 3,
injectorStage = true injectorStage = false
), ),
// new IBusCachedPlugin( // new IBusCachedPlugin(
// resetVector = 0x80000000l, // resetVector = 0x80000000l,

View File

@ -203,6 +203,7 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] {
when(execute.input(IS_EBREAK)){ when(execute.input(IS_EBREAK)){
when(execute.arbitration.isValid ) { when(execute.arbitration.isValid ) {
iBusFetcher.flushIt()
iBusFetcher.haltIt() iBusFetcher.haltIt()
decode.arbitration.flushAll := True decode.arbitration.flushAll := True
} }

View File

@ -31,6 +31,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
assert(!(cmdToRspStageCount == 1 && !injectorStage)) assert(!(cmdToRspStageCount == 1 && !injectorStage))
assert(!(compressedGen && !decodePcGen)) assert(!(compressedGen && !decodePcGen))
var fetcherHalt : Bool = null var fetcherHalt : Bool = null
var fetcherflushIt : Bool = null
lazy val pcValids = Vec(Bool, 4) lazy val pcValids = Vec(Bool, 4)
def pcValid(stage : Stage) = pcValids(pipeline.indexOf(stage)) def pcValid(stage : Stage) = pcValids(pipeline.indexOf(stage))
var incomingInstruction : Bool = null var incomingInstruction : Bool = null
@ -45,6 +46,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
var predictionJumpInterface : Flow[UInt] = null var predictionJumpInterface : Flow[UInt] = null
override def haltIt(): Unit = fetcherHalt := True override def haltIt(): Unit = fetcherHalt := True
override def flushIt(): Unit = fetcherflushIt := True
case class JumpInfo(interface : Flow[UInt], stage: Stage, priority : Int) case class JumpInfo(interface : Flow[UInt], stage: Stage, priority : Int)
val jumpInfos = ArrayBuffer[JumpInfo]() val jumpInfos = ArrayBuffer[JumpInfo]()
@ -58,6 +60,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
// var decodeExceptionPort : Flow[ExceptionCause] = null // var decodeExceptionPort : Flow[ExceptionCause] = null
override def setup(pipeline: VexRiscv): Unit = { override def setup(pipeline: VexRiscv): Unit = {
fetcherHalt = False fetcherHalt = False
fetcherflushIt = False
incomingInstruction = False incomingInstruction = False
if(catchAccessFault) { if(catchAccessFault) {
val exceptionService = pipeline.service(classOf[ExceptionService]) val exceptionService = pipeline.service(classOf[ExceptionService])
@ -100,10 +103,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
pcLoad.payload := MuxOH(OHMasking.first(valids.asBits), pcs) pcLoad.payload := MuxOH(OHMasking.first(valids.asBits), pcs)
} }
def flush = jump.pcLoad.valid || fetcherflushIt
val killLastStage = jump.pcLoad.valid || decode.arbitration.isRemoved
def flush = killLastStage
class PcFetch extends Area{ class PcFetch extends Area{
val preOutput = Stream(UInt(32 bits)) val preOutput = Stream(UInt(32 bits))
@ -296,7 +296,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
incomingInstruction setWhen (inputBeforeStage.valid) incomingInstruction setWhen (inputBeforeStage.valid)
} }
val decodeInput = (if (injectorStage) { val decodeInput = (if (injectorStage) {
val decodeInput = inputBeforeStage.m2sPipeWithFlush(killLastStage, collapsBubble = false) val decodeInput = inputBeforeStage.m2sPipeWithFlush(flush, collapsBubble = false)
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck, decode.input(INSTRUCTION), inputBeforeStage.rsp.inst) decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck, decode.input(INSTRUCTION), inputBeforeStage.rsp.inst)
iBusRsp.readyForError.clearWhen(decodeInput.valid) iBusRsp.readyForError.clearWhen(decodeInput.valid)
incomingInstruction setWhen (decodeInput.valid) incomingInstruction setWhen (decodeInput.valid)
@ -323,15 +323,17 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
} }
val nextPcCalc = if (decodePcGen) { val nextPcCalc = if (decodePcGen) {
val valids = pcUpdatedGen(True, List(execute, memory, writeBack).map(_.arbitration.isStuck), true) val valids = pcUpdatedGen(True, False :: List(execute, memory, writeBack).map(_.arbitration.isStuck), true)
pcValids := Vec(valids.takeRight(4)) pcValids := Vec(valids.takeRight(4))
} else new Area{ } else new Area{
val valids = pcUpdatedGen(True, iBusRsp.inputPipeline.map(!_.ready) ++ (if (injectorStage) List(!decodeInput.ready) else Nil) ++ List(execute, memory, writeBack).map(_.arbitration.isStuck), relaxedPcCalculation) val valids = pcUpdatedGen(True, iBusRsp.inputPipeline.map(!_.ready) ++ (if (injectorStage) List(!decodeInput.ready) else Nil) ++ List(execute, memory, writeBack).map(_.arbitration.isStuck), relaxedPcCalculation)
pcValids := Vec(valids.takeRight(4)) pcValids := Vec(valids.takeRight(4))
} }
val decodeRemoved = RegInit(False) setWhen(decode.arbitration.isRemoved) clearWhen(!decode.arbitration.isStuck)
decodeInput.ready := !decode.arbitration.isStuck decodeInput.ready := !decode.arbitration.isStuck
decode.arbitration.isValid := decodeInput.valid decode.arbitration.isValid := decodeInput.valid && !decodeRemoved
decode.insert(PC) := (if (decodePcGen) decodePc.pcReg else decodeInput.pc) decode.insert(PC) := (if (decodePcGen) decodePc.pcReg else decodeInput.pc)
decode.insert(INSTRUCTION) := decodeInput.rsp.inst decode.insert(INSTRUCTION) := decodeInput.rsp.inst
decode.insert(INSTRUCTION_READY) := True decode.insert(INSTRUCTION_READY) := True

View File

@ -401,7 +401,7 @@ public:
} }
#endif #endif
bool failed = false;
try { try {
// run simulation for 100 clock periods // run simulation for 100 clock periods
for (i = 16; i < timeout*2; i+=2) { for (i = 16; i < timeout*2; i+=2) {
@ -501,6 +501,7 @@ public:
cout << "FAIL " << name << endl; cout << "FAIL " << name << endl;
cycles += instanceCycles; cycles += instanceCycles;
staticMutex.unlock(); staticMutex.unlock();
failed = true;
} }
@ -510,6 +511,12 @@ public:
#ifdef TRACE #ifdef TRACE
tfp->close(); tfp->close();
#endif #endif
#ifdef STOP_ON_FAIL
if(failed){
sleep(1);
exit(-1);
}
#endif
return this; return this;
} }
}; };
@ -1908,25 +1915,31 @@ int main(int argc, char **argv, char **env) {
#ifdef FREERTOS #ifdef FREERTOS
//redo(1,Workspace("freeRTOS_demo").loadHex("../../resources/hex/freeRTOS_demo.hex")->bootAt(0x80000000u)->run(100e6);) //redo(1,Workspace("freeRTOS_demo").loadHex("../../resources/hex/freeRTOS_demo.hex")->bootAt(0x80000000u)->run(100e6);)
queue<std::function<void()>> tasks; vector <std::function<void()>> tasks;
for(const string &name : freeRtosTests){ for(const string &name : freeRtosTests){
tasks.push([=]() { Workspace(name + "_rv32i_O0").loadHex("../../resources/freertos/" + name + "_rv32i_O0.hex")->bootAt(0x80000000u)->run(4e6*15);}); tasks.push_back([=]() { Workspace(name + "_rv32i_O0").loadHex("../../resources/freertos/" + name + "_rv32i_O0.hex")->bootAt(0x80000000u)->run(4e6*15);});
tasks.push([=]() { Workspace(name + "_rv32i_O3").loadHex("../../resources/freertos/" + name + "_rv32i_O3.hex")->bootAt(0x80000000u)->run(4e6*15);}); tasks.push_back([=]() { Workspace(name + "_rv32i_O3").loadHex("../../resources/freertos/" + name + "_rv32i_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
#ifdef COMPRESSED #ifdef COMPRESSED
tasks.push([=]() { Workspace(name + "_rv32ic_O0").loadHex("../../resources/freertos/" + name + "_rv32ic_O0.hex")->bootAt(0x80000000u)->run(4e6*15);}); tasks.push_back([=]() { Workspace(name + "_rv32ic_O0").loadHex("../../resources/freertos/" + name + "_rv32ic_O0.hex")->bootAt(0x80000000u)->run(4e6*15);});
tasks.push([=]() { Workspace(name + "_rv32ic_O3").loadHex("../../resources/freertos/" + name + "_rv32ic_O3.hex")->bootAt(0x80000000u)->run(4e6*15);}); tasks.push_back([=]() { Workspace(name + "_rv32ic_O3").loadHex("../../resources/freertos/" + name + "_rv32ic_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
#endif #endif
#if defined(MUL) && defined(DIV) #if defined(MUL) && defined(DIV)
#ifdef COMPRESSED #ifdef COMPRESSED
tasks.push([=]() { Workspace(name + "_rv32imac_O3").loadHex("../../resources/freertos/" + name + "_rv32imac_O3.hex")->bootAt(0x80000000u)->run(4e6*15);}); tasks.push_back([=]() { Workspace(name + "_rv32imac_O3").loadHex("../../resources/freertos/" + name + "_rv32imac_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
#else #else
tasks.push([=]() { Workspace(name + "_rv32im_O3").loadHex("../../resources/freertos/" + name + "_rv32im_O3.hex")->bootAt(0x80000000u)->run(4e6*15);}); tasks.push_back([=]() { Workspace(name + "_rv32im_O3").loadHex("../../resources/freertos/" + name + "_rv32im_O3.hex")->bootAt(0x80000000u)->run(4e6*15);});
#endif #endif
#endif #endif
} }
multiThreadedExecute(tasks); while(tasks.size() > FREERTOS_COUNT){
tasks.erase(tasks.begin() + (rand()%tasks.size()));
}
queue <std::function<void()>> tasksSelected(std::deque<std::function<void()>>(tasks.begin(), tasks.end()));
multiThreadedExecute(tasksSelected);
#endif #endif
} }

View File

@ -23,6 +23,7 @@ REF_TIME=no
THREAD_COUNT?=4 THREAD_COUNT?=4
MTIME_INSTR_FACTOR?=no MTIME_INSTR_FACTOR?=no
COMPRESSED?=no COMPRESSED?=no
STOP_ON_FAIL?=no
ADDCFLAGS += -CFLAGS -DIBUS_${IBUS} ADDCFLAGS += -CFLAGS -DIBUS_${IBUS}
@ -40,6 +41,11 @@ ifeq ($(DHRYSTONE),yes)
ADDCFLAGS += -CFLAGS -DDHRYSTONE ADDCFLAGS += -CFLAGS -DDHRYSTONE
endif endif
ifeq ($(STOP_ON_FAIL),yes)
ADDCFLAGS += -CFLAGS -DSTOP_ON_FAIL
endif
ifeq ($(NO_STALL),yes) ifeq ($(NO_STALL),yes)
ADDCFLAGS += -CFLAGS -DSTALL=0 ADDCFLAGS += -CFLAGS -DSTALL=0
else else
@ -116,6 +122,12 @@ endif
ADDCFLAGS += -CFLAGS -DTRACE_START=${TRACE_START} ADDCFLAGS += -CFLAGS -DTRACE_START=${TRACE_START}
ifeq ($(FREERTOS),yes) ifeq ($(FREERTOS),yes)
ADDCFLAGS += -CFLAGS -DFREERTOS ADDCFLAGS += -CFLAGS -DFREERTOS
ADDCFLAGS += -CFLAGS -DFREERTOS_COUNT=99999
endif
ifneq ($(FREERTOS),no)
ADDCFLAGS += -CFLAGS -DFREERTOS
ADDCFLAGS += -CFLAGS -DFREERTOS_COUNT=$(FREERTOS)
endif endif
all: clean run all: clean run

View File

@ -15,9 +15,12 @@ import scala.sys.process._
import scala.util.Random import scala.util.Random
abstract class ConfigUniverse
abstract class ConfigDimension[T](val name: String) { abstract class ConfigDimension[T](val name: String) {
def positions: Seq[T] def positions: Seq[T]
def default : Seq[T] = List(positions(0)) def default : Seq[T] = List(positions(0))
def random(universes : Seq[ConfigUniverse], r : Random) : T = positions(r.nextInt(positions.length))
} }
abstract class VexRiscvDimension(name: String) extends ConfigDimension[VexRiscvPosition](name) abstract class VexRiscvDimension(name: String) extends ConfigDimension[VexRiscvPosition](name)
@ -32,6 +35,15 @@ abstract class VexRiscvPosition(name: String) extends ConfigPosition[VexRiscvCo
def testParam : String = "" def testParam : String = ""
} }
class VexRiscvUniverse extends ConfigUniverse
object VexRiscvUniverse{
val CATCH_ALL = new VexRiscvUniverse
val MMU = new VexRiscvUniverse
val universes = List(CATCH_ALL, MMU)
}
class ShiftDimension extends VexRiscvDimension("Shift") { class ShiftDimension extends VexRiscvDimension("Shift") {
override val positions = List( override val positions = List(
new VexRiscvPosition("FullLate") { new VexRiscvPosition("FullLate") {
@ -361,18 +373,32 @@ class DBusDimension extends VexRiscvDimension("DBus") {
trait CatchAllPosition trait CatchAllPosition
//TODO CSR without exception
//TODO FREERTOS
class CsrDimension extends VexRiscvDimension("Csr") { class CsrDimension extends VexRiscvDimension("Csr") {
override val positions = List( override val positions = List(
// new VexRiscvPosition("None") { new VexRiscvPosition("None") {
// override def applyOn(config: VexRiscvConfig): Unit = {} override def applyOn(config: VexRiscvConfig): Unit = {}
// override def testParam = "CSR=no" override def testParam = "CSR=no"
// }, },
new VexRiscvPosition("All") with CatchAllPosition{ new VexRiscvPosition("All") with CatchAllPosition{
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.all(0x80000020l)) override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new CsrPlugin(CsrPluginConfig.all(0x80000020l))
} }
) )
} }
class DebugDimension extends VexRiscvDimension("Debug") {
override val positions = List(
new VexRiscvPosition("None") {
override def applyOn(config: VexRiscvConfig): Unit = {}
override def testParam = "DEBUG_PLUGIN=no"
},
new VexRiscvPosition("Enable") with CatchAllPosition{
override def applyOn(config: VexRiscvConfig): Unit = config.plugins += new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset")))
}
)
}
class DecoderDimension extends VexRiscvDimension("Decoder") { class DecoderDimension extends VexRiscvDimension("Decoder") {
override val positions = (for(catchAll <- List(false,true)) yield List( override val positions = (for(catchAll <- List(false,true)) yield List(
new VexRiscvPosition("") { new VexRiscvPosition("") {
@ -418,7 +444,8 @@ class TestIndividualFeatures extends FunSuite {
new RegFileDimension, new RegFileDimension,
new SrcDimension, new SrcDimension,
new CsrDimension, new CsrDimension,
new DecoderDimension new DecoderDimension,
new DebugDimension
) )
@ -451,7 +478,9 @@ class TestIndividualFeatures extends FunSuite {
} }
test(prefix + name + "_test") { test(prefix + name + "_test") {
val debug = false val debug = false
val stdCmd = if(debug) "make clean run REDO=1 TRACE=yes MMU=no DEBUG_PLUGIN=no DHRYSTONE=no " else "make clean run REDO=10 TRACE=yess MMU=no DEBUG_PLUGIN=no " val stdCmd = if(debug) "make clean run REDO=1 TRACE=yes MMU=no DHRYSTONE=no " else "make clean run REDO=10 TRACE=no MMU=no "
// val stdCmd = "make clean run REDO=40 DHRYSTONE=no STOP_ON_FAIL=yes TRACE=yess MMU=no"
val testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ") val testCmd = stdCmd + (positionsToApply).map(_.testParam).mkString(" ")
val str = doCmd(testCmd) val str = doCmd(testCmd)
assert(!str.contains("FAIL")) assert(!str.contains("FAIL"))
@ -462,13 +491,24 @@ class TestIndividualFeatures extends FunSuite {
dimensions.foreach(d => d.positions.foreach(p => p.dimension = d)) dimensions.foreach(d => d.positions.foreach(p => p.dimension = d))
val testId = None
val seed = Random.nextLong()
// val testId = Some(6)
// val seed = -6369023953274056616l
val rand = new Random(seed)
println(s"Seed=$seed")
for(i <- 0 until 200){ for(i <- 0 until 200){
var positions : List[VexRiscvPosition] = null var positions : List[VexRiscvPosition] = null
val universe = VexRiscvUniverse.universes.filter(e => rand.nextBoolean())
do{ do{
positions = dimensions.map(d => d.positions(Random.nextInt(d.positions.size))) positions = dimensions.map(d => d.random(universe, rand))
}while(!positions.forall(_.isCompatibleWith(positions))) }while(!positions.forall(_.isCompatibleWith(positions)))
doTest(positions," random_" + i + "_")
if(testId.isEmpty || testId.get == i)
doTest(positions," random_" + i + "_")
} }
println(s"${usedPositions.size}/$positionsCount positions") println(s"${usedPositions.size}/$positionsCount positions")