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
|
val nSlaves = addressMap.size
|
||||||
// !!! handle hmastlock
|
|
||||||
|
|
||||||
// Setup diversions infront of each master
|
// Setup diversions infront of each master
|
||||||
val diversions = Seq.tabulate(nMasters) { m => Module(new MasterDiversion) }
|
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 masters = diversions map (_.io.out)
|
||||||
val slaves = io.slaves
|
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
|
// This matrix governs the master-slave connections in the address phase
|
||||||
// It is indexed by addressPhaseGrantSM(slave)(master)
|
// It is indexed by addressPhaseGrantSM(slave)(master)
|
||||||
// It is guaranteed to have at most one 'true' per column and per row
|
// 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(_ || _) }
|
.reduce(_ || _) }
|
||||||
|
|
||||||
// Requested access to slaves from masters (pre-arbitration)
|
// 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
|
// 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.
|
// 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;
|
// 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).
|
// 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) } }
|
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)
|
// 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) => {
|
(slaves zip addressPhaseGrantSM) foreach { case (s, g) => {
|
||||||
s.htrans := Mux1H(g, masters.map(_.htrans)) // defaults to HTRANS_IDLE (0)
|
s.htrans := Mux1H(g, masters.map(_.htrans)) // defaults to HTRANS_IDLE (0)
|
||||||
s.haddr := Mux1H(g, masters.map(_.haddr))
|
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.hwrite := Mux1H(g, masters.map(_.hwrite))
|
||||||
s.hsize := Mux1H(g, masters.map(_.hsize))
|
s.hsize := Mux1H(g, masters.map(_.hsize))
|
||||||
s.hburst := Mux1H(g, masters.map(_.hburst))
|
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) => {
|
(slaves zip dataPhaseGrantSM) foreach { case (s, g) => {
|
||||||
s.hwdata := Mux1H(g, masters.map(_.hwdata))
|
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) {
|
class HastiBus(amap: Seq[UInt=>Bool])(implicit p: Parameters) extends HastiModule()(p) {
|
||||||
|
Loading…
Reference in New Issue
Block a user