Fix CsrPlugin pipelined option

This commit is contained in:
Dolu1990 2018-11-05 16:22:41 +01:00
parent 662d76e3aa
commit b7f3ee5e06
2 changed files with 37 additions and 10 deletions

View File

@ -161,11 +161,12 @@ class SimpleBusSlaveFactory(bus: SimpleBus) extends BusSlaveFactoryDelayed{
override def wordAddressInc: Int = busDataWidth / 8 override def wordAddressInc: Int = busDataWidth / 8
} }
case class SimpleBusDecoder(busConfig : SimpleBusConfig, mappings : Seq[AddressMapping], pendingMax : Int = 7) extends Component{ case class SimpleBusDecoder(busConfig : SimpleBusConfig, mappings : Seq[AddressMapping], pendingMax : Int = 3) extends Component{
val io = new Bundle { val io = new Bundle {
val input = slave(SimpleBus(busConfig)) val input = slave(SimpleBus(busConfig))
val outputs = Vec(master(SimpleBus(busConfig)), mappings.size) val outputs = Vec(master(SimpleBus(busConfig)), mappings.size)
} }
val hasDefault = mappings.contains(DefaultMapping)
val hits = Vec(Bool, mappings.size) val hits = Vec(Bool, mappings.size)
for((slaveBus, memorySpace, hit) <- (io.outputs, mappings, hits).zipped) yield { for((slaveBus, memorySpace, hit) <- (io.outputs, mappings, hits).zipped) yield {
hit := (memorySpace match { hit := (memorySpace match {
@ -175,14 +176,14 @@ case class SimpleBusDecoder(busConfig : SimpleBusConfig, mappings : Seq[AddressM
slaveBus.cmd.valid := io.input.cmd.valid && hit slaveBus.cmd.valid := io.input.cmd.valid && hit
slaveBus.cmd.payload := io.input.cmd.payload.resized slaveBus.cmd.payload := io.input.cmd.payload.resized
} }
val noHit = !hits.orR val noHit = if(!hasDefault) !hits.orR else False
io.input.cmd.ready := (hits,io.outputs).zipped.map(_ && _.cmd.ready).orR || noHit io.input.cmd.ready := (hits,io.outputs).zipped.map(_ && _.cmd.ready).orR || noHit
val rspPendingCounter = Reg(UInt(log2Up(pendingMax + 1) bits)) init(0) val rspPendingCounter = Reg(UInt(log2Up(pendingMax + 1) bits)) init(0)
rspPendingCounter := rspPendingCounter + U(io.input.cmd.fire && !io.input.cmd.wr) - U(io.input.rsp.valid) rspPendingCounter := rspPendingCounter + U(io.input.cmd.fire && !io.input.cmd.wr) - U(io.input.rsp.valid)
val rspHits = RegNextWhen(hits, io.input.cmd.fire) val rspHits = RegNextWhen(hits, io.input.cmd.fire)
val rspPending = rspPendingCounter =/= 0 val rspPending = rspPendingCounter =/= 0
val rspNoHit = !rspHits.orR val rspNoHit = if(!hasDefault) !rspHits.orR else False
io.input.rsp.valid := io.outputs.map(_.rsp.valid).orR || (rspPending && rspNoHit) io.input.rsp.valid := io.outputs.map(_.rsp.valid).orR || (rspPending && rspNoHit)
io.input.rsp.payload := io.outputs.map(_.rsp.payload).read(OHToUInt(rspHits)) io.input.rsp.payload := io.outputs.map(_.rsp.payload).read(OHToUInt(rspHits))

View File

@ -66,6 +66,7 @@ case class CsrPluginConfig(
satpAccess : CsrAccess = CsrAccess.NONE, satpAccess : CsrAccess = CsrAccess.NONE,
medelegAccess : CsrAccess = CsrAccess.NONE, medelegAccess : CsrAccess = CsrAccess.NONE,
midelegAccess : CsrAccess = CsrAccess.NONE, midelegAccess : CsrAccess = CsrAccess.NONE,
pipelineCsrRead : Boolean = false,
deterministicInteruptionEntry : Boolean = false //Only used for simulatation purposes deterministicInteruptionEntry : Boolean = false //Only used for simulatation purposes
){ ){
assert(!ucycleAccess.canWrite) assert(!ucycleAccess.canWrite)
@ -261,6 +262,7 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
object IS_CSR extends Stageable(Bool) object IS_CSR extends Stageable(Bool)
object CSR_WRITE_OPCODE extends Stageable(Bool) object CSR_WRITE_OPCODE extends Stageable(Bool)
object CSR_READ_OPCODE extends Stageable(Bool) object CSR_READ_OPCODE extends Stageable(Bool)
object PIPELINED_CSR_READ extends Stageable(Bits(32 bits))
var allowInterrupts : Bool = null var allowInterrupts : Bool = null
var allowException : Bool = null var allowException : Bool = null
@ -282,7 +284,8 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
val defaultCsrActions = List[(Stageable[_ <: BaseType],Any)]( val defaultCsrActions = List[(Stageable[_ <: BaseType],Any)](
IS_CSR -> True, IS_CSR -> True,
REGFILE_WRITE_VALID -> True, REGFILE_WRITE_VALID -> True,
BYPASSABLE_MEMORY_STAGE -> True BYPASSABLE_EXECUTE_STAGE -> False,
BYPASSABLE_MEMORY_STAGE -> True
) ++ (if(catchIllegalAccess) List(HAS_SIDE_EFFECT -> True) else Nil) ) ++ (if(catchIllegalAccess) List(HAS_SIDE_EFFECT -> True) else Nil)
val nonImmediatActions = defaultCsrActions ++ List( val nonImmediatActions = defaultCsrActions ++ List(
@ -785,26 +788,49 @@ class CsrPlugin(config: CsrPluginConfig) extends Plugin[VexRiscv] with Exception
val imm = IMM(input(INSTRUCTION)) val imm = IMM(input(INSTRUCTION))
val writeSrc = input(SRC1) def writeSrc = input(SRC1)
// val readDataValid = True
val readData = B(0, 32 bits) val readData = B(0, 32 bits)
val writeInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_WRITE_OPCODE)
val readInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_READ_OPCODE)
val writeEnable = writeInstruction && ! arbitration.isStuck // && readDataRegValid
val readEnable = readInstruction && ! arbitration.isStuck // && !readDataRegValid
// def readDataReg = memory.input(REGFILE_WRITE_DATA) //PIPE OPT // def readDataReg = memory.input(REGFILE_WRITE_DATA) //PIPE OPT
// val readDataRegValid = Reg(Bool) setWhen(arbitration.isValid) clearWhen(!arbitration.isStuck) // val readDataRegValid = Reg(Bool) setWhen(arbitration.isValid) clearWhen(!arbitration.isStuck)
// val writeDataEnable = input(INSTRUCTION)(13) ? writeSrc | B"xFFFFFFFF"
// val writeData = if(noCsrAlu) writeSrc else input(INSTRUCTION)(13).mux(
// False -> writeSrc,
// True -> Mux(input(INSTRUCTION)(12), ~writeSrc, writeSrc)
// )
val writeData = if(noCsrAlu) writeSrc else input(INSTRUCTION)(13).mux( val writeData = if(noCsrAlu) writeSrc else input(INSTRUCTION)(13).mux(
False -> writeSrc, False -> writeSrc,
True -> Mux(input(INSTRUCTION)(12), readData & ~writeSrc, readData | writeSrc) True -> Mux(input(INSTRUCTION)(12), readData & ~writeSrc, readData | writeSrc)
) )
val writeInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_WRITE_OPCODE)
val readInstruction = arbitration.isValid && input(IS_CSR) && input(CSR_READ_OPCODE)
// arbitration.haltItself setWhen(writeInstruction && !readDataRegValid) // arbitration.haltItself setWhen(writeInstruction && !readDataRegValid)
val writeEnable = writeInstruction && ! arbitration.isStuck// && readDataRegValid
val readEnable = readInstruction && ! arbitration.isStuck// && !readDataRegValid
when(arbitration.isValid && input(IS_CSR)) { when(arbitration.isValid && input(IS_CSR)) {
output(REGFILE_WRITE_DATA) := readData if(!pipelineCsrRead) output(REGFILE_WRITE_DATA) := readData
arbitration.haltItself setWhen(blockedBySideEffects) arbitration.haltItself setWhen(blockedBySideEffects)
} }
if(pipelineCsrRead){
insert(PIPELINED_CSR_READ) := readData
when(memory.arbitration.isValid && memory.input(IS_CSR)) {
memory.output(REGFILE_WRITE_DATA) := memory.input(PIPELINED_CSR_READ)
}
}
//
// Component.current.rework{
// when(arbitration.isFiring && input(IS_CSR)) {
// memory.input(REGFILE_WRITE_DATA).getDrivingReg := readData
// }
// }
//Translation of the csrMapping into real logic //Translation of the csrMapping into real logic
val csrAddress = input(INSTRUCTION)(csrRange) val csrAddress = input(INSTRUCTION)(csrRange)