mirror of
https://github.com/SpinalHDL/VexRiscv.git
synced 2025-01-03 03:43:39 -05:00
IBusSimplePlugin fully functional Need to restore branch prediction
This commit is contained in:
parent
ac74fb9ce8
commit
1fb138de1f
10 changed files with 72 additions and 34 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue