ahb: support hmastlock acquistion of crossbar
This commit is contained in:
		@@ -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) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user