ahb: support hmastlock acquistion of crossbar
This commit is contained in:
parent
e1e8eda419
commit
200c69c106
@ -171,7 +171,6 @@ class HastiXbar(nMasters: Int, addressMap: Seq[UInt=>Bool])(implicit p: Paramete
|
||||
}
|
||||
|
||||
val nSlaves = addressMap.size
|
||||
// !!! handle hmastlock
|
||||
|
||||
// Setup diversions infront of each master
|
||||
val diversions = Seq.tabulate(nMasters) { m => Module(new MasterDiversion) }
|
||||
@ -181,6 +180,10 @@ class HastiXbar(nMasters: Int, addressMap: Seq[UInt=>Bool])(implicit p: Paramete
|
||||
val masters = diversions map (_.io.out)
|
||||
val slaves = io.slaves
|
||||
|
||||
// Lock status of the crossbar
|
||||
val lockedM = Reg(init = Vec.fill(nMasters)(Bool(false)))
|
||||
val isLocked = lockedM.reduce(_ || _)
|
||||
|
||||
// This matrix governs the master-slave connections in the address phase
|
||||
// It is indexed by addressPhaseGrantSM(slave)(master)
|
||||
// It is guaranteed to have at most one 'true' per column and per row
|
||||
@ -247,11 +250,12 @@ class HastiXbar(nMasters: Int, addressMap: Seq[UInt=>Bool])(implicit p: Paramete
|
||||
.reduce(_ || _) }
|
||||
|
||||
// Requested access to slaves from masters (pre-arbitration)
|
||||
// NOTE: quash any request that requires bus ownership or conflicts with isLocked
|
||||
// NOTE: isNSeq does NOT include SEQ; thus, masters who are midburst do not
|
||||
// request access to a new slave. They stay tied to the old and do not get two.
|
||||
// NOTE: if a master was waited, it must repeat the same request as last cycle;
|
||||
// thus, it will request the same slave and not end up with two (unless buggy).
|
||||
val NSeq = Vec(masters.map(_.isNSeq()))
|
||||
val NSeq = Vec((lockedM zip masters) map { case(l, m) => m.isNSeq() && ((!isLocked && !m.hmastlock) || l) })
|
||||
val requestSM = Vec.tabulate(nSlaves) { s => Vec.tabulate(nMasters) { m => matchMS(m)(s) && NSeq(m) && !bubbleM(m) } }
|
||||
|
||||
// Select at most one master request per slave (lowest index = highest priority)
|
||||
@ -281,7 +285,7 @@ class HastiXbar(nMasters: Int, addressMap: Seq[UInt=>Bool])(implicit p: Paramete
|
||||
(slaves zip addressPhaseGrantSM) foreach { case (s, g) => {
|
||||
s.htrans := Mux1H(g, masters.map(_.htrans)) // defaults to HTRANS_IDLE (0)
|
||||
s.haddr := Mux1H(g, masters.map(_.haddr))
|
||||
s.hmastlock := Mux1H(g, masters.map(_.hmastlock)) // !!! use global crossbar lock state
|
||||
s.hmastlock := isLocked
|
||||
s.hwrite := Mux1H(g, masters.map(_.hwrite))
|
||||
s.hsize := Mux1H(g, masters.map(_.hsize))
|
||||
s.hburst := Mux1H(g, masters.map(_.hburst))
|
||||
@ -293,6 +297,20 @@ class HastiXbar(nMasters: Int, addressMap: Seq[UInt=>Bool])(implicit p: Paramete
|
||||
(slaves zip dataPhaseGrantSM) foreach { case (s, g) => {
|
||||
s.hwdata := Mux1H(g, masters.map(_.hwdata))
|
||||
} }
|
||||
|
||||
// When no master-slave connections are active, a master can take-over the bus
|
||||
val canLock = !addressPhaseGrantSM.map({ v => v.reduce(_ || _) }).reduce(_ || _)
|
||||
|
||||
// Lowest index highest priority for lock arbitration
|
||||
val reqLock = masters.map(_.hmastlock)
|
||||
val winLock = PriorityEncoderOH(reqLock)
|
||||
|
||||
// Lock arbitration
|
||||
when (isLocked) {
|
||||
lockedM := (lockedM zip reqLock) map { case (a,b) => a && b }
|
||||
} .elsewhen (canLock) {
|
||||
lockedM := winLock
|
||||
}
|
||||
}
|
||||
|
||||
class HastiBus(amap: Seq[UInt=>Bool])(implicit p: Parameters) extends HastiModule()(p) {
|
||||
|
Loading…
Reference in New Issue
Block a user