Skip to content

Commit

Permalink
Fix pmp write when there is hazard due to the register file.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu1990 committed Jun 7, 2021
1 parent 87f100d commit 646911a
Showing 1 changed file with 23 additions and 21 deletions.
44 changes: 23 additions & 21 deletions src/main/scala/vexriscv/plugin/PmpPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,11 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
val csrService = pipeline.service(classOf[CsrInterface])
val privilegeService = pipeline.service(classOf[PrivilegeService])

val pmpaddr = Mem(UInt(xlen bits), regions)
val pmpcfg = Vector.fill(regions)(Reg(Bits(8 bits)) init(0))
val base, mask = Vector.fill(regions)(Reg(UInt(xlen - cutoff bits)))
val state = pipeline plug new Area {
val pmpaddr = Mem(UInt(xlen bits), regions)
val pmpcfg = Vector.fill(regions)(Reg(Bits(8 bits)) init (0))
val base, mask = Vector.fill(regions)(Reg(UInt(xlen - cutoff bits)))
}

def machineMode : Bool = privilegeService.isMachine()

Expand Down Expand Up @@ -154,14 +156,14 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
when (pmpcfgCsr) {
csrService.allowCsr()
csrService.readData() :=
pmpcfg(pmpcfgN @@ U(3, 2 bits)) ##
pmpcfg(pmpcfgN @@ U(2, 2 bits)) ##
pmpcfg(pmpcfgN @@ U(1, 2 bits)) ##
pmpcfg(pmpcfgN @@ U(0, 2 bits))
state.pmpcfg(pmpcfgN @@ U(3, 2 bits)) ##
state.pmpcfg(pmpcfgN @@ U(2, 2 bits)) ##
state.pmpcfg(pmpcfgN @@ U(1, 2 bits)) ##
state.pmpcfg(pmpcfgN @@ U(0, 2 bits))
}
when (pmpaddrCsr) {
csrService.allowCsr()
csrService.readData() := pmpaddr(pmpNcfg).asBits
csrService.readData() := state.pmpaddr(pmpNcfg).asBits
}
}
}
Expand All @@ -170,7 +172,7 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
when ((pmpcfgCsr | pmpaddrCsr) & machineMode) {
csrService.allowCsr()
arbitration.haltItself := !fsmComplete
when (!fsmPending) {
when (!fsmPending && hazardFree) {
fsmPending := True
writeData_ := csrService.writeData()
pmpNcfg_ := pmpNcfg
Expand All @@ -193,7 +195,7 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
fsmCounter := 0
}
whenIsActive {
when (fsmPending & hazardFree) {
when (fsmPending) {
goto(stateWrite)
}
}
Expand All @@ -204,15 +206,15 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
when (pmpcfgCsr_) {
val overwrite = writeData_.subdivideIn(8 bits)
for (i <- 0 until 4) {
when (~pmpcfg(pmpcfgN_ @@ U(i, 2 bits))(lBit)) {
pmpcfg(pmpcfgN_ @@ U(i, 2 bits)).assignFromBits(overwrite(i))
when (~state.pmpcfg(pmpcfgN_ @@ U(i, 2 bits))(lBit)) {
state.pmpcfg(pmpcfgN_ @@ U(i, 2 bits)).assignFromBits(overwrite(i))
}
}
goto(stateCfg)
}
when (pmpaddrCsr_) {
when (~pmpcfg(pmpNcfg_)(lBit)) {
pmpaddr(pmpNcfg_) := writeData_.asUInt
when (~state.pmpcfg(pmpNcfg_)(lBit)) {
state.pmpaddr(pmpNcfg_) := writeData_.asUInt
}
goto(stateAddr)
}
Expand All @@ -238,26 +240,26 @@ class PmpPlugin(regions : Int, granularity : Int, ioRange : UInt => Bool) extend
when (pmpaddrCsr_) {
setter.io.addr := writeData_.asUInt
} otherwise {
setter.io.addr := pmpaddr(fsmCounter)
setter.io.addr := state.pmpaddr(fsmCounter)
}

when (fsmEnable & ~pmpcfg(fsmCounter)(lBit)) {
base(fsmCounter) := setter.io.base
mask(fsmCounter) := setter.io.mask
when (fsmEnable & ~state.pmpcfg(fsmCounter)(lBit)) {
state.base(fsmCounter) := setter.io.base
state.mask(fsmCounter) := setter.io.mask
}
}
}

pipeline plug new Area {
def getHits(address : UInt) = {
(0 until regions).map(i =>
((address & mask(U(i, log2Up(regions) bits))) === base(U(i, log2Up(regions) bits))) &
(pmpcfg(i)(lBit) | ~machineMode) & (pmpcfg(i)(aBits) === NAPOT)
((address & state.mask(U(i, log2Up(regions) bits))) === state.base(U(i, log2Up(regions) bits))) &
(state.pmpcfg(i)(lBit) | ~machineMode) & (state.pmpcfg(i)(aBits) === NAPOT)
)
}

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 {
Expand Down

0 comments on commit 646911a

Please sign in to comment.