IBusSimplePlugin fully functional Need to restore branch prediction

This commit is contained in:
Dolu1990 2018-03-20 00:01:28 +01:00
parent ac74fb9ce8
commit 1fb138de1f
10 changed files with 72 additions and 34 deletions

View file

@ -126,7 +126,7 @@ trait Pipeline {
for(stageIndex <- 1 until stages.length){
val stageBefore = stages(stageIndex - 1)
val stage = stages(stageIndex)
stage.arbitration.isValid.setAsReg() init(False)
when(!stage.arbitration.isStuck || stage.arbitration.removeIt) {
stage.arbitration.isValid := False
}

View file

@ -49,7 +49,7 @@ class Stage() extends Area{
val removeIt = False //When settable, unschedule the instruction as if it was never executed (no side effect)
val flushAll = False //When settable, unschedule instructions in the current stage and all prior ones
val redoIt = False //Allow to notify that a given instruction in a pipeline is rescheduled
val isValid = RegInit(False) //Inform if a instruction is in the current stage
val isValid = Bool //Inform if a instruction is in the current stage
val isStuck = Bool //Inform if the instruction is stuck (haltItself || haltByOther)
val isStuckByOthers = Bool //Inform if the instruction is stuck by sombody else
def isRemoved = removeIt //Inform if the instruction is going to be unschedule the current cycle

View file

@ -57,7 +57,7 @@ object TestsWorkspace {
// portTlbSize = 4
// )
// ),
//// new DBusSimplePlugin(
// new DBusSimplePlugin(
// catchAddressMisaligned = true,
// catchAccessFault = true,
// earlyInjection = false
@ -122,7 +122,7 @@ object TestsWorkspace {
),
// new DivPlugin,
new CsrPlugin(CsrPluginConfig.all(0x80000020l).copy(deterministicInteruptionEntry = false)),
// new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new DebugPlugin(ClockDomain.current.clone(reset = Bool().setName("debugReset"))),
new BranchPlugin(
earlyBranch = true,
catchAddressMisaligned = true,

View file

@ -22,6 +22,7 @@ case class VexRiscvConfig(plugins : Seq[Plugin[VexRiscv]]){
object REGFILE_WRITE_VALID extends Stageable(Bool)
object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits))
object SRC1 extends Stageable(Bits(32 bits))
object SRC2 extends Stageable(Bits(32 bits))
object SRC_ADD_SUB extends Stageable(Bits(32 bits))

View file

@ -291,7 +291,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
override def build(pipeline: VexRiscv): Unit = {
import pipeline._
import pipeline.config._
val fetcher = service(classOf[IBusFetcher])
pipeline plug new Area{
//Define CSR mapping utilities
@ -376,8 +376,11 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
//Used to make the pipeline empty softly (for interrupts)
val pipelineLiberator = new Area{
val enable = False.noBackendCombMerge //Verilator Perf
decode.arbitration.haltByOther setWhen(enable) //TODO FETCH
val done = ! List(execute, memory, writeBack).map(_.arbitration.isValid).orR
when(enable){
fetcher.haltIt()
}
val done = ! List(decode, execute, memory, writeBack).map(_.arbitration.isValid).orR && fetcher.nextPc()._1
// val done = History(doneAsync, 0 to 0).andR
}
@ -389,7 +392,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
val exceptionValidsRegs = Vec(Reg(Bool) init(False), stages.length).allowUnsetRegToAvoidLatch
val exceptionContext = Reg(ExceptionCause())
pipelineLiberator.enable setWhen(exceptionValidsRegs.tail.orR)
pipelineLiberator.enable setWhen(exceptionValidsRegs.orR)
val groupedByStage = exceptionPortsInfos.map(_.stage).distinct.map(s => {
val stagePortsInfos = exceptionPortsInfos.filter(_.stage == s).sortWith(_.priority > _.priority)
@ -497,7 +500,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
mstatus.MPP := privilege
mepc := exception mux(
True -> writeBack.input(PC),
False -> (writeBackWasWfi ? writeBack.input(PC) | decode.input(PC))
False -> fetcher.nextPc()._2
)
mcause.interrupt := interrupt
@ -529,10 +532,10 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
}
//Manage WFI instructions
if(wfiGen) when(execute.arbitration.isValid && execute.input(ENV_CTRL) === EnvCtrlEnum.WFI){
if(wfiGen) when(decode.arbitration.isValid && decode.input(ENV_CTRL) === EnvCtrlEnum.WFI){
when(!interrupt){
execute.arbitration.haltItself := True
decode.arbitration.flushAll := True
fetcher.haltIt()
decode.arbitration.haltItself := True
}
}

View file

@ -134,6 +134,7 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
import pipeline.config._
val logic = debugClockDomain {pipeline plug new Area{
val iBusFetcher = service(classOf[IBusFetcher])
val insertDecodeInstruction = False
val firstCycle = RegNext(False) setWhen (io.bus.cmd.ready)
val secondCycle = RegNext(firstCycle)
@ -141,7 +142,7 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
val haltIt = RegInit(False)
val stepIt = RegInit(False)
val isPipActive = RegNext(List(decode, execute, memory, writeBack).map(_.arbitration.isValid).orR)
val isPipActive = RegNext(List(decode,execute, memory, writeBack).map(_.arbitration.isValid).orR)
val isPipBusy = isPipActive || RegNext(isPipActive)
val haltedByBreak = RegInit(False)
@ -173,9 +174,9 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
is(1) {
when(io.bus.cmd.wr) {
insertDecodeInstruction := True
decode.arbitration.isValid setWhen (firstCycle)
decode.arbitration.isValid.getDrivingReg setWhen (firstCycle)
decode.arbitration.haltItself setWhen (secondCycle)
io.bus.cmd.ready := !(firstCycle || secondCycle || decode.arbitration.isValid)
io.bus.cmd.ready := !firstCycle && !secondCycle && execute.arbitration.isValid
}
}
}
@ -209,7 +210,8 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] w
}
when(haltIt) {
decode.arbitration.haltByOther := True
iBusFetcher.haltIt()
// decode.arbitration.haltByOther := True
}
when(stepIt && decode.arbitration.isFiring) {

View file

@ -96,7 +96,9 @@ object IBusSimpleBus{
maximumPendingReadTransactions = 8
)
}
case class IBusSimpleBus(interfaceKeepData : Boolean) extends Bundle with IMasterSlave{
case class IBusSimpleBus(interfaceKeepData : Boolean) extends Bundle with IMasterSlave {
var cmd = Stream(IBusSimpleCmd())
var rsp = Flow(IBusSimpleRsp())
@ -148,12 +150,24 @@ case class IBusSimpleBus(interfaceKeepData : Boolean) extends Bundle with IMaste
}
}
class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean, pendingMax : Int = 7) extends Plugin[VexRiscv] with JumpService{
trait IBusFetcher{
def haltIt() : Unit
def nextPc() : (Bool, UInt)
}
class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean, pendingMax : Int = 7) extends Plugin[VexRiscv] with JumpService with IBusFetcher{
var iBus : IBusSimpleBus = null
var prefetchExceptionPort : Flow[ExceptionCause] = null
def resetVector = BigInt(0x80000000l)
def keepPcPlus4 = false
lazy val fetcherHalt = False
lazy val decodeNextPcValid = Bool
lazy val decodeNextPc = UInt(32 bits)
def nextPc() = (decodeNextPcValid, decodeNextPc)
override def haltIt(): Unit = fetcherHalt := True
case class JumpInfo(interface : Flow[UInt], stage: Stage, priority : Int)
val jumpInfos = ArrayBuffer[JumpInfo]()
override def createJumpInterface(stage: Stage, priority : Int = 0): Flow[UInt] = {
@ -258,10 +272,14 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean,
val injector = new Area {
val input = iBusRsp.output.s2mPipe(flush)
val stage = input.m2sPipe(flush, false)
val inputBeforeHalt = iBusRsp.output.s2mPipe(flush)
val input = inputBeforeHalt.haltWhen(fetcherHalt)
val stage = input.m2sPipe(flush || decode.arbitration.isRemoved)
decodeNextPcValid := RegNext(inputBeforeHalt.isStall)
decodeNextPc := decode.input(PC)
stage.ready := !decode.arbitration.isStuck
decode.arbitration.isValid.setAsComb().removeAssignments()
decode.arbitration.isValid := stage.valid
decode.insert(PC) := stage.pc
decode.insert(INSTRUCTION) := stage.rsp.inst

View file

@ -25,7 +25,7 @@ object KeepAttribute{
class PcManagerSimplePlugin(resetVector : BigInt,
relaxedPcCalculation : Boolean = false,
keepPcPlus4 : Boolean = true) extends Plugin[VexRiscv]{
override def build(pipeline: VexRiscv): Unit = ???
override def build(pipeline: VexRiscv): Unit = {println("PcManagerSimplePlugin is now useless")}
}

View file

@ -182,7 +182,7 @@ public:
double cyclesPerSecond = 10e6;
double allowedCycles = 0.0;
uint32_t bootPc = -1;
uint32_t iStall = 1,dStall = 1;
uint32_t iStall = STALL,dStall = STALL;
#ifdef TRACE
VerilatedVcdC* tfp;
#endif
@ -433,14 +433,21 @@ public:
dump(i + 1);
if(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_valid == 1 && top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address != 0){
regTraces <<
#ifdef TRACE_WITH_TIME
currentTime <<
#endif
" PC " << hex << setw(8) << top->VexRiscv->writeBack_PC << " : reg[" << dec << setw(2) << (uint32_t)top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address << "] = " << hex << setw(8) << top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data << endl;
}
if(top->VexRiscv->writeBack_arbitration_isFiring){
if(top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_valid == 1 && top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address != 0){
regTraces <<
#ifdef TRACE_WITH_TIME
currentTime <<
#endif
" PC " << hex << setw(8) << top->VexRiscv->writeBack_PC << " : reg[" << dec << setw(2) << (uint32_t)top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_address << "] = " << hex << setw(8) << top->VexRiscv->writeBack_RegFilePlugin_regFileWrite_payload_data << endl;
} else {
regTraces <<
#ifdef TRACE_WITH_TIME
currentTime <<
#endif
" PC " << hex << setw(8) << top->VexRiscv->writeBack_PC << endl;
}
}
for(SimElement* simElement : simElements) simElement->preCycle();
@ -1429,7 +1436,7 @@ public:
int error;
if((error = recv(clientSocket, buffer, 4, 0)) != 4){
printf("Should read 4 bytes, had %d", error);
fail();
while(1);
}
return *((uint32_t*) buffer);
@ -1502,7 +1509,7 @@ public:
while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);}
if((readValue = readCmd(2,debugAddress + 4)) != 0x80000014){
printf("wrong break PC 2 %x\n",readValue);
printf("wrong break PC 3 %x\n",readValue);
clientFail = true; return;
}
@ -1523,7 +1530,7 @@ public:
while((readCmd(2,debugAddress) & RISCV_SPINAL_FLAGS_HALT) == 0){usleep(100);}
if((readValue = readCmd(2,debugAddress + 4)) != 0x80000024){
printf("wrong break PC 2 %x\n",readValue);
printf("wrong break PC 3 %x\n",readValue);
clientFail = true; return;
}

View file

@ -9,6 +9,7 @@ DIV?=yes
CSR?=yes
MMU?=yes
ATOMIC?=no
NO_STALL?=no
DEBUG_PLUGIN?=STD
DEBUG_PLUGIN_EXTERNAL?=no
CUSTOM_SIMD_ADD?=no
@ -34,6 +35,12 @@ ifeq ($(DHRYSTONE),yes)
ADDCFLAGS += -CFLAGS -DDHRYSTONE
endif
ifeq ($(NO_STALL),yes)
ADDCFLAGS += -CFLAGS -DSTALL=0
else
ADDCFLAGS += -CFLAGS -DSTALL=1
endif
ifneq ($(MTIME_INSTR_FACTOR),no)
ADDCFLAGS += -CFLAGS -DMTIME_INSTR_FACTOR=${MTIME_INSTR_FACTOR}
endif