Csr/Mmu ensure implement that SFENCE_VMA flush the next instructions

SAT flush reworked a bit too
This commit is contained in:
Dolu1990 2021-05-28 13:35:52 +02:00
parent 4b0763b43d
commit 4490254d3d
2 changed files with 26 additions and 12 deletions

View File

@ -474,6 +474,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
object ENV_CTRL extends Stageable(EnvCtrlEnum())
object IS_CSR extends Stageable(Bool)
object IS_SFENCE_VMA extends Stageable(Bool)
object CSR_WRITE_OPCODE extends Stageable(Bool)
object CSR_READ_OPCODE extends Stageable(Bool)
object PIPELINED_CSR_READ extends Stageable(Bits(32 bits))
@ -606,6 +607,11 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
if(withExternalMhartid) externalMhartId = in UInt(mhartidWidth bits)
if(utimeAccess != CsrAccess.NONE) utime = in UInt(64 bits) setName("utime")
if(supervisorGen) {
decoderService.addDefault(IS_SFENCE_VMA, False)
decoderService.add(SFENCE_VMA, List(IS_SFENCE_VMA -> True))
}
}
def inhibateInterrupts() : Unit = allowInterrupts := False
@ -783,10 +789,15 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
satpAccess(CSR.SATP, 31 -> satp.MODE, 22 -> satp.ASID, 0 -> satp.PPN)
val satpLogic = supervisorGen generate new Area {
val rescheduleLogic = supervisorGen generate new Area {
redoInterface.valid := False
redoInterface.payload := decode.input(PC)
duringWrite(CSR.SATP) {
val rescheduleNext = False
when(execute.arbitration.isValid && execute.input(IS_SFENCE_VMA)) { rescheduleNext := True }
duringWrite(CSR.SATP) { rescheduleNext := True }
when(rescheduleNext){
redoInterface.valid := True
execute.arbitration.flushNext := True
decode.arbitration.haltByOther := True
@ -1155,8 +1166,12 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
when(arbitration.isValid && input(IS_CSR)) {
if(!pipelineCsrRead) output(REGFILE_WRITE_DATA) := readData
}
when(arbitration.isValid && (input(IS_CSR) || (if(supervisorGen) input(IS_SFENCE_VMA) else False))) {
arbitration.haltItself setWhen(blockedBySideEffects)
}
if(pipelineCsrRead){
insert(PIPELINED_CSR_READ) := readData
when(memory.arbitration.isValid && memory.input(IS_CSR)) {

View File

@ -53,13 +53,13 @@ class MmuPlugin(ioRange : UInt => Bool,
port.bus
}
object IS_SFENCE_VMA extends Stageable(Bool)
object IS_SFENCE_VMA2 extends Stageable(Bool)
override def setup(pipeline: VexRiscv): Unit = {
import Riscv._
import pipeline.config._
val decoderService = pipeline.service(classOf[DecoderService])
decoderService.addDefault(IS_SFENCE_VMA, False)
decoderService.add(SFENCE_VMA, List(IS_SFENCE_VMA -> True))
decoderService.addDefault(IS_SFENCE_VMA2, False)
decoderService.add(SFENCE_VMA, List(IS_SFENCE_VMA2 -> True))
dBusAccess = pipeline.service(classOf[DBusAccessService]).newDBusAccess()
@ -296,18 +296,17 @@ class MmuPlugin(ioRange : UInt => Bool,
}
}
val fenceStage = stages.last
val fenceStage = execute
//Both SFENCE_VMA and SATP reschedule the next instruction in the CsrPlugin itself with one extra cycle to ensure side effect propagation.
fenceStage plug new Area{
import fenceStage._
when(arbitration.isValid && input(IS_SFENCE_VMA)){
for(port <- core.ports; line <- port.cache) line.valid := False //Assume that the instruction already fetched into the pipeline are ok
when(arbitration.isValid && arbitration.isFiring && input(IS_SFENCE_VMA2)){
for(port <- core.ports; line <- port.cache) line.valid := False
}
csrService.duringWrite(CSR.SATP){
csrService.onWrite(CSR.SATP){
for(port <- core.ports; line <- port.cache) line.valid := False
core.ports.filter(_.handle.args.earlyRequireMmuLockup).foreach{p =>
p.dirty := True
}
}
}
}