diff --git a/uncore/src/main/scala/prci.scala b/uncore/src/main/scala/prci.scala index 2dee3ae8..3d59d16b 100644 --- a/uncore/src/main/scala/prci.scala +++ b/uncore/src/main/scala/prci.scala @@ -25,27 +25,29 @@ class PRCITileIO(implicit p: Parameters) extends Bundle { override def cloneType: this.type = new PRCITileIO().asInstanceOf[this.type] } +/** Power, Reset, Clock, Interrupt */ class PRCI(implicit val p: Parameters) extends Module with HasTileLinkParameters with HasAddrMapParameters { val io = new Bundle { - val id = UInt(INPUT, log2Up(p(NTiles))) - val interrupts = new Bundle { + val interrupts = Vec(p(NTiles), new Bundle { val mtip = Bool() val meip = Bool() val seip = Bool() val debug = Bool() - }.asInput + }).asInput val tl = new ClientUncachedTileLinkIO().flip - val tile = new PRCITileIO + val tiles = Vec(p(NTiles), new PRCITileIO) } - val ipi = Reg(init=Bool(false)) + val ipi = Reg(init=Vec.fill(p(NTiles))(Bool(false))) val acq = Queue(io.tl.acquire, 1) + val addr = acq.bits.full_addr() val read = acq.bits.isBuiltInType(Acquire.getType) val write = acq.bits.isBuiltInType(Acquire.putType) - val rdata = Wire(init=ipi) + val rdata = Wire(init=UInt(0)) + val masked_wdata = (acq.bits.data & acq.bits.full_wmask()) | (rdata & ~acq.bits.full_wmask()) io.tl.grant.valid := acq.valid acq.ready := io.tl.grant.ready io.tl.grant.bits := Grant( @@ -56,15 +58,25 @@ class PRCI(implicit val p: Parameters) extends Module addr_beat = UInt(0), data = rdata) - val regSize = 16 - val nRegs = 2 - val addr = acq.bits.full_addr()(log2Up(regSize*nRegs)-1,log2Up(regSize)) - - when (addr === UInt(0) && write) { - ipi := acq.bits.data(0) + when (write) { + val ipiRegBytes = 4 + val regsPerBeat = tlDataBytes/ipiRegBytes + val word = + if (regsPerBeat >= ipi.size) UInt(0) + else addr(log2Up(ipi.size*ipiRegBytes)-1,log2Up(tlDataBytes)) + for (i <- 0 until ipi.size by regsPerBeat) { + when (word === i/regsPerBeat) { + rdata := Cat(ipi.slice(i, i + regsPerBeat).map(p => Cat(UInt(0, 8*ipiRegBytes-1), p)).reverse) + for (j <- 0 until (regsPerBeat min (ipi.size - i))) { + when (write) { ipi(i+j) := masked_wdata(j*8*ipiRegBytes) } + } + } + } } - io.tile.interrupts := io.interrupts - io.tile.interrupts.msip := ipi - io.tile.id := io.id + for ((tile, i) <- io.tiles zipWithIndex) { + tile.interrupts := io.interrupts(i) + tile.interrupts.msip := ipi(i) + tile.id := UInt(i) + } }