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{
def haltIt() : Unit
def flushIt() : Unit
def incoming() : Bool
def pcValid(stage : Stage) : Bool
def getInjectionPort() : Stream[Bits]

View File

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

View File

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

View File

@ -31,6 +31,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
assert(!(cmdToRspStageCount == 1 && !injectorStage))
assert(!(compressedGen && !decodePcGen))
var fetcherHalt : Bool = null
var fetcherflushIt : Bool = null
lazy val pcValids = Vec(Bool, 4)
def pcValid(stage : Stage) = pcValids(pipeline.indexOf(stage))
var incomingInstruction : Bool = null
@ -45,6 +46,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
var predictionJumpInterface : Flow[UInt] = null
override def haltIt(): Unit = fetcherHalt := True
override def flushIt(): Unit = fetcherflushIt := True
case class JumpInfo(interface : Flow[UInt], stage: Stage, priority : Int)
val jumpInfos = ArrayBuffer[JumpInfo]()
@ -58,6 +60,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
// var decodeExceptionPort : Flow[ExceptionCause] = null
override def setup(pipeline: VexRiscv): Unit = {
fetcherHalt = False
fetcherflushIt = False
incomingInstruction = False
if(catchAccessFault) {
val exceptionService = pipeline.service(classOf[ExceptionService])
@ -100,10 +103,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
pcLoad.payload := MuxOH(OHMasking.first(valids.asBits), pcs)
}
val killLastStage = jump.pcLoad.valid || decode.arbitration.isRemoved
def flush = killLastStage
def flush = jump.pcLoad.valid || fetcherflushIt
class PcFetch extends Area{
val preOutput = Stream(UInt(32 bits))
@ -296,7 +296,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
incomingInstruction setWhen (inputBeforeStage.valid)
}
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)
iBusRsp.readyForError.clearWhen(decodeInput.valid)
incomingInstruction setWhen (decodeInput.valid)
@ -323,15 +323,17 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
}
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))
} 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)
pcValids := Vec(valids.takeRight(4))
}
val decodeRemoved = RegInit(False) setWhen(decode.arbitration.isRemoved) clearWhen(!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(INSTRUCTION) := decodeInput.rsp.inst
decode.insert(INSTRUCTION_READY) := True

View File

@ -401,7 +401,7 @@ public:
}
#endif
bool failed = false;
try {
// run simulation for 100 clock periods
for (i = 16; i < timeout*2; i+=2) {
@ -501,6 +501,7 @@ public:
cout << "FAIL " << name << endl;
cycles += instanceCycles;
staticMutex.unlock();
failed = true;
}
@ -510,6 +511,12 @@ public:
#ifdef TRACE
tfp->close();
#endif
#ifdef STOP_ON_FAIL
if(failed){
sleep(1);
exit(-1);
}
#endif
return this;
}
};
@ -1908,25 +1915,31 @@ int main(int argc, char **argv, char **env) {
#ifdef FREERTOS
//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){
tasks.push([=]() { 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_O0").loadHex("../../resources/freertos/" + name + "_rv32i_O0.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
tasks.push([=]() { 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_O0").loadHex("../../resources/freertos/" + name + "_rv32ic_O0.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
#if defined(MUL) && defined(DIV)
#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
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
}
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
}

View File

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

View File

@ -15,9 +15,12 @@ import scala.sys.process._
import scala.util.Random
abstract class ConfigUniverse
abstract class ConfigDimension[T](val name: String) {
def positions: Seq[T]
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)
@ -32,6 +35,15 @@ abstract class VexRiscvPosition(name: String) extends ConfigPosition[VexRiscvCo
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") {
override val positions = List(
new VexRiscvPosition("FullLate") {
@ -361,18 +373,32 @@ class DBusDimension extends VexRiscvDimension("DBus") {
trait CatchAllPosition
//TODO CSR without exception
//TODO FREERTOS
class CsrDimension extends VexRiscvDimension("Csr") {
override val positions = List(
// new VexRiscvPosition("None") {
// override def applyOn(config: VexRiscvConfig): Unit = {}
// override def testParam = "CSR=no"
// },
new VexRiscvPosition("None") {
override def applyOn(config: VexRiscvConfig): Unit = {}
override def testParam = "CSR=no"
},
new VexRiscvPosition("All") with CatchAllPosition{
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") {
override val positions = (for(catchAll <- List(false,true)) yield List(
new VexRiscvPosition("") {
@ -418,7 +444,8 @@ class TestIndividualFeatures extends FunSuite {
new RegFileDimension,
new SrcDimension,
new CsrDimension,
new DecoderDimension
new DecoderDimension,
new DebugDimension
)
@ -451,7 +478,9 @@ class TestIndividualFeatures extends FunSuite {
}
test(prefix + name + "_test") {
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 str = doCmd(testCmd)
assert(!str.contains("FAIL"))
@ -462,12 +491,23 @@ class TestIndividualFeatures extends FunSuite {
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){
var positions : List[VexRiscvPosition] = null
val universe = VexRiscvUniverse.universes.filter(e => rand.nextBoolean())
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)))
if(testId.isEmpty || testId.get == i)
doTest(positions," random_" + i + "_")
}