Fix pmp write when there is hazard due to the register file.

This commit is contained in:
Dolu1990 2021-06-07 17:30:47 +02:00
parent 87f100dac1
commit 646911a373
1 changed files with 23 additions and 21 deletions

View File

@ -124,9 +124,11 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
val csrService = pipeline.service(classOf[CsrInterface]) val csrService = pipeline.service(classOf[CsrInterface])
val privilegeService = pipeline.service(classOf[PrivilegeService]) val privilegeService = pipeline.service(classOf[PrivilegeService])
val state = pipeline plug new Area {
val pmpaddr = Mem(UInt(xlen bits), regions) val pmpaddr = Mem(UInt(xlen bits), regions)
val pmpcfg = Vector.fill(regions)(Reg(Bits(8 bits)) init (0)) val pmpcfg = Vector.fill(regions)(Reg(Bits(8 bits)) init (0))
val base, mask = Vector.fill(regions)(Reg(UInt(xlen - cutoff bits))) val base, mask = Vector.fill(regions)(Reg(UInt(xlen - cutoff bits)))
}
def machineMode : Bool = privilegeService.isMachine() def machineMode : Bool = privilegeService.isMachine()
@ -154,14 +156,14 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
when (pmpcfgCsr) { when (pmpcfgCsr) {
csrService.allowCsr() csrService.allowCsr()
csrService.readData() := csrService.readData() :=
pmpcfg(pmpcfgN @@ U(3, 2 bits)) ## state.pmpcfg(pmpcfgN @@ U(3, 2 bits)) ##
pmpcfg(pmpcfgN @@ U(2, 2 bits)) ## state.pmpcfg(pmpcfgN @@ U(2, 2 bits)) ##
pmpcfg(pmpcfgN @@ U(1, 2 bits)) ## state.pmpcfg(pmpcfgN @@ U(1, 2 bits)) ##
pmpcfg(pmpcfgN @@ U(0, 2 bits)) state.pmpcfg(pmpcfgN @@ U(0, 2 bits))
} }
when (pmpaddrCsr) { when (pmpaddrCsr) {
csrService.allowCsr() csrService.allowCsr()
csrService.readData() := pmpaddr(pmpNcfg).asBits csrService.readData() := state.pmpaddr(pmpNcfg).asBits
} }
} }
} }
@ -170,7 +172,7 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
when ((pmpcfgCsr | pmpaddrCsr) & machineMode) { when ((pmpcfgCsr | pmpaddrCsr) & machineMode) {
csrService.allowCsr() csrService.allowCsr()
arbitration.haltItself := !fsmComplete arbitration.haltItself := !fsmComplete
when (!fsmPending) { when (!fsmPending && hazardFree) {
fsmPending := True fsmPending := True
writeData_ := csrService.writeData() writeData_ := csrService.writeData()
pmpNcfg_ := pmpNcfg pmpNcfg_ := pmpNcfg
@ -193,7 +195,7 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
fsmCounter := 0 fsmCounter := 0
} }
whenIsActive { whenIsActive {
when (fsmPending & hazardFree) { when (fsmPending) {
goto(stateWrite) goto(stateWrite)
} }
} }
@ -204,15 +206,15 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
when (pmpcfgCsr_) { when (pmpcfgCsr_) {
val overwrite = writeData_.subdivideIn(8 bits) val overwrite = writeData_.subdivideIn(8 bits)
for (i <- 0 until 4) { for (i <- 0 until 4) {
when (~pmpcfg(pmpcfgN_ @@ U(i, 2 bits))(lBit)) { when (~state.pmpcfg(pmpcfgN_ @@ U(i, 2 bits))(lBit)) {
pmpcfg(pmpcfgN_ @@ U(i, 2 bits)).assignFromBits(overwrite(i)) state.pmpcfg(pmpcfgN_ @@ U(i, 2 bits)).assignFromBits(overwrite(i))
} }
} }
goto(stateCfg) goto(stateCfg)
} }
when (pmpaddrCsr_) { when (pmpaddrCsr_) {
when (~pmpcfg(pmpNcfg_)(lBit)) { when (~state.pmpcfg(pmpNcfg_)(lBit)) {
pmpaddr(pmpNcfg_) := writeData_.asUInt state.pmpaddr(pmpNcfg_) := writeData_.asUInt
} }
goto(stateAddr) goto(stateAddr)
} }
@ -238,12 +240,12 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
when (pmpaddrCsr_) { when (pmpaddrCsr_) {
setter.io.addr := writeData_.asUInt setter.io.addr := writeData_.asUInt
} otherwise { } otherwise {
setter.io.addr := pmpaddr(fsmCounter) setter.io.addr := state.pmpaddr(fsmCounter)
} }
when (fsmEnable & ~pmpcfg(fsmCounter)(lBit)) { when (fsmEnable & ~state.pmpcfg(fsmCounter)(lBit)) {
base(fsmCounter) := setter.io.base state.base(fsmCounter) := setter.io.base
mask(fsmCounter) := setter.io.mask state.mask(fsmCounter) := setter.io.mask
} }
} }
} }
@ -251,13 +253,13 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
pipeline plug new Area { pipeline plug new Area {
def getHits(address : UInt) = { def getHits(address : UInt) = {
(0 until regions).map(i => (0 until regions).map(i =>
((address & mask(U(i, log2Up(regions) bits))) === base(U(i, log2Up(regions) bits))) & ((address & state.mask(U(i, log2Up(regions) bits))) === state.base(U(i, log2Up(regions) bits))) &
(pmpcfg(i)(lBit) | ~machineMode) & (pmpcfg(i)(aBits) === NAPOT) (state.pmpcfg(i)(lBit) | ~machineMode) & (state.pmpcfg(i)(aBits) === NAPOT)
) )
} }
def getPermission(hits : IndexedSeq[Bool], bit : Int) = { def getPermission(hits : IndexedSeq[Bool], bit : Int) = {
(hits zip pmpcfg).map({ case (i, cfg) => i & cfg(bit) }).orR (hits zip state.pmpcfg).map({ case (i, cfg) => i & cfg(bit) }).orR
} }
val dGuard = new Area { val dGuard = new Area {