add CsrPlugin.csrOhDecoder

This commit is contained in:
Charles Papon 2020-03-05 00:13:04 +01:00
parent 50ec0a1917
commit 58af94269e
1 changed files with 76 additions and 41 deletions

View File

@ -69,6 +69,7 @@ case class CsrPluginConfig(
midelegAccess : CsrAccess = CsrAccess.NONE, midelegAccess : CsrAccess = CsrAccess.NONE,
pipelineCsrRead : Boolean = false, pipelineCsrRead : Boolean = false,
pipelinedInterrupt : Boolean = true, pipelinedInterrupt : Boolean = true,
csrOhDecoder : Boolean = true,
deterministicInteruptionEntry : Boolean = false, //Only used for simulatation purposes deterministicInteruptionEntry : Boolean = false, //Only used for simulatation purposes
wfiOutput : Boolean = false wfiOutput : Boolean = false
){ ){
@ -263,7 +264,7 @@ case class CsrReadToWriteOverride(that : Data, bitOffset : Int) //Used for speci
case class CsrOnWrite(doThat :() => Unit) case class CsrOnWrite(doThat :() => Unit)
case class CsrOnRead(doThat : () => Unit) case class CsrOnRead(doThat : () => Unit)
case class CsrMapping() extends CsrInterface{ case class CsrMapping() extends CsrInterface{
val mapping = mutable.HashMap[Int,ArrayBuffer[Any]]() val mapping = mutable.LinkedHashMap[Int,ArrayBuffer[Any]]()
def addMappingAt(address : Int,that : Any) = mapping.getOrElseUpdate(address,new ArrayBuffer[Any]) += that def addMappingAt(address : Int,that : Any) = mapping.getOrElseUpdate(address,new ArrayBuffer[Any]) += that
override def r(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrRead(that,bitOffset)) override def r(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrRead(that,bitOffset))
override def w(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrWrite(that,bitOffset)) override def w(csrAddress : Int, bitOffset : Int, that : Data): Unit = addMappingAt(csrAddress, CsrWrite(that,bitOffset))
@ -997,7 +998,7 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
val imm = IMM(input(INSTRUCTION)) val imm = IMM(input(INSTRUCTION))
def writeSrc = input(SRC1) def writeSrc = input(SRC1)
// val readDataValid = True // val readDataValid = True
val readData = B(0, 32 bits) val readData = Bits(32 bits)
val writeInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_WRITE_OPCODE) val writeInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_WRITE_OPCODE)
val readInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_READ_OPCODE) val readInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_READ_OPCODE)
val writeEnable = writeInstruction && ! blockedBySideEffects && !arbitration.isStuckByOthers// && readDataRegValid val writeEnable = writeInstruction && ! blockedBySideEffects && !arbitration.isStuckByOthers// && readDataRegValid
@ -1043,10 +1044,8 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
//Translation of the csrMapping into real logic //Translation of the csrMapping into real logic
val csrAddress = input(INSTRUCTION)(csrRange) val csrAddress = input(INSTRUCTION)(csrRange)
Component.current.addPrePopTask(() => { Component.current.afterElaboration{
switch(csrAddress) { def doJobs(jobs : ArrayBuffer[Any]): Unit ={
for ((address, jobs) <- csrMapping.mapping) {
is(address) {
val withWrite = jobs.exists(j => j.isInstanceOf[CsrWrite] || j.isInstanceOf[CsrOnWrite]) val withWrite = jobs.exists(j => j.isInstanceOf[CsrWrite] || j.isInstanceOf[CsrOnWrite])
val withRead = jobs.exists(j => j.isInstanceOf[CsrRead] || j.isInstanceOf[CsrOnRead]) val withRead = jobs.exists(j => j.isInstanceOf[CsrRead] || j.isInstanceOf[CsrOnRead])
if(withRead && withWrite) { if(withRead && withWrite) {
@ -1065,11 +1064,6 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
} }
} }
for (element <- jobs) element match {
case element: CsrRead if element.that.getBitsWidth != 0 => readData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
case _ =>
}
when(readEnable) { when(readEnable) {
for (element <- jobs) element match { for (element <- jobs) element match {
case element: CsrOnRead => case element: CsrOnRead =>
@ -1078,23 +1072,64 @@ class CsrPlugin(val config: CsrPluginConfig) extends Plugin[VexRiscv] with Excep
} }
} }
} }
}
}
switch(csrAddress) { def doJobsOverride(jobs : ArrayBuffer[Any]): Unit ={
for ((address, jobs) <- csrMapping.mapping if jobs.exists(_.isInstanceOf[CsrReadToWriteOverride])) {
is(address) {
for (element <- jobs) element match { for (element <- jobs) element match {
case element: CsrReadToWriteOverride if element.that.getBitsWidth != 0 => readToWriteData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits case element: CsrReadToWriteOverride if element.that.getBitsWidth != 0 => readToWriteData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
case _ => case _ =>
} }
} }
csrOhDecoder match {
case false => {
readData := 0
switch(csrAddress) {
for ((address, jobs) <- csrMapping.mapping) {
is(address) {
doJobs(jobs)
for (element <- jobs) element match {
case element: CsrRead if element.that.getBitsWidth != 0 => readData(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
case _ =>
}
}
}
}
switch(csrAddress) {
for ((address, jobs) <- csrMapping.mapping if jobs.exists(_.isInstanceOf[CsrReadToWriteOverride])) {
is(address) {
doJobsOverride(jobs)
}
}
}
}
case true => {
val oh = csrMapping.mapping.keys.toList.distinct.map(address => address -> RegNextWhen(decode.input(INSTRUCTION)(csrRange) === address, !execute.arbitration.isStuck).setCompositeName(this, "csr_" + address)).toMap
val readDatas = ArrayBuffer[Bits]()
for ((address, jobs) <- csrMapping.mapping) {
when(oh(address)){
doJobs(jobs)
}
if(jobs.exists(_.isInstanceOf[CsrRead])) {
val masked = B(0, 32 bits)
when(oh(address)) (for (element <- jobs) element match {
case element: CsrRead if element.that.getBitsWidth != 0 => masked(element.bitOffset, element.that.getBitsWidth bits) := element.that.asBits
case _ =>
})
readDatas += masked
}
}
readData := readDatas.reduceBalancedTree(_ | _)
for ((address, jobs) <- csrMapping.mapping) {
when(oh(address)){
doJobsOverride(jobs)
}
}
} }
} }
illegalAccess setWhen(privilege < csrAddress(9 downto 8).asUInt) illegalAccess setWhen(privilege < csrAddress(9 downto 8).asUInt)
illegalAccess clearWhen(!arbitration.isValid || !input(IS_CSR)) illegalAccess clearWhen(!arbitration.isValid || !input(IS_CSR))
}) }
} }
} }
} }