diff --git a/uncore/src/coherence.scala b/uncore/src/coherence.scala index e8aad9d0..96fd475d 100644 --- a/uncore/src/coherence.scala +++ b/uncore/src/coherence.scala @@ -3,6 +3,10 @@ package uncore import Chisel._ import Constants._ +trait CoherenceAgent +trait ClientCoherenceAgent extends CoherenceAgent +trait MasterCoherenceAgent extends CoherenceAgent + object cpuCmdToRW { def apply(cmd: Bits): (Bool, Bool) = (isRead(cmd) || isPrefetch(cmd), isWrite(cmd)) } diff --git a/uncore/src/package.scala b/uncore/src/package.scala index a3af64e1..137cc74d 100644 --- a/uncore/src/package.scala +++ b/uncore/src/package.scala @@ -35,7 +35,7 @@ class BasicCrossbar[T <: Data]()(data: => T)(implicit conf: PhysicalNetworkConfi case class LogicalNetworkConfiguration(nEndpoints: Int, idBits: Int, nHubs: Int, nTiles: Int) -abstract class LogicalNetwork[TileLinkType <: Bundle](endpoints: Seq[Component])(implicit conf: LogicalNetworkConfiguration) extends Component { +abstract class LogicalNetwork[TileLinkType <: Bundle](endpoints: Seq[CoherenceAgent])(implicit conf: LogicalNetworkConfiguration) extends Component { val io: Vec[TileLinkType] val physicalNetworks: Seq[PhysicalNetwork] require(endpoints.length == conf.nEndpoints) @@ -63,5 +63,6 @@ class TileLink(implicit conf: LogicalNetworkConfiguration) extends Bundle { val xact_rep = (new HubIO) { new TransactionReply } val xact_finish = (new TileIO) { new TransactionFinish } val incoherent = Bool(OUTPUT) + override def clone = { new TileLink().asInstanceOf[this.type] } } } diff --git a/uncore/src/uncore.scala b/uncore/src/uncore.scala index e2dcfc30..99136c1b 100644 --- a/uncore/src/uncore.scala +++ b/uncore/src/uncore.scala @@ -3,13 +3,13 @@ package uncore import Chisel._ import Constants._ -class TrackerProbeData(implicit conf: UncoreConfiguration) extends Bundle { - val tile_id = Bits(width = conf.tile_id_bits) +class TrackerProbeData(implicit conf: CoherenceHubConfiguration) extends Bundle { + val tile_id = Bits(width = conf.ln.idBits) } -class TrackerAllocReq(implicit conf: UncoreConfiguration) extends Bundle { +class TrackerAllocReq(implicit conf: CoherenceHubConfiguration) extends Bundle { val xact_init = new TransactionInit() - val tile_id = Bits(width = conf.tile_id_bits) + val tile_id = Bits(width = conf.ln.idBits) override def clone = { new TrackerAllocReq().asInstanceOf[this.type] } } @@ -17,16 +17,16 @@ class TrackerDependency extends Bundle { val global_xact_id = Bits(width = GLOBAL_XACT_ID_BITS) } -class XactTracker(id: Int)(implicit conf: UncoreConfiguration) extends Component { +class XactTracker(id: Int)(implicit conf: CoherenceHubConfiguration) extends Component { val co = conf.co val io = new Bundle { val alloc_req = (new FIFOIO) { new TrackerAllocReq }.flip val p_data = (new PipeIO) { new TrackerProbeData }.flip val can_alloc = Bool(INPUT) val xact_finish = Bool(INPUT) - val p_rep_cnt_dec = Bits(INPUT, conf.ntiles) - val p_req_cnt_inc = Bits(INPUT, conf.ntiles) - val tile_incoherent = Bits(INPUT, conf.ntiles) + val p_rep_cnt_dec = Bits(INPUT, conf.ln.nTiles) + val p_req_cnt_inc = Bits(INPUT, conf.ln.nTiles) + val tile_incoherent = Bits(INPUT, conf.ln.nTiles) val p_rep_data = (new PipeIO) { new ProbeReplyData }.flip val x_init_data = (new PipeIO) { new TransactionInitData }.flip val sent_x_rep_ack = Bool(INPUT) @@ -39,18 +39,18 @@ class XactTracker(id: Int)(implicit conf: UncoreConfiguration) extends Component val probe_req = (new FIFOIO) { new ProbeRequest } val busy = Bool(OUTPUT) val addr = Bits(OUTPUT, PADDR_BITS - OFFSET_BITS) - val init_tile_id = Bits(OUTPUT, conf.tile_id_bits) - val p_rep_tile_id = Bits(OUTPUT, conf.tile_id_bits) + val init_tile_id = Bits(OUTPUT, conf.ln.idBits) + val p_rep_tile_id = Bits(OUTPUT, conf.ln.idBits) val tile_xact_id = Bits(OUTPUT, TILE_XACT_ID_BITS) - val sharer_count = Bits(OUTPUT, conf.tile_id_bits+1) + val sharer_count = Bits(OUTPUT, conf.ln.idBits+1) val x_type = Bits(OUTPUT, X_INIT_TYPE_MAX_BITS) - val push_p_req = Bits(OUTPUT, conf.ntiles) - val pop_p_rep = Bits(OUTPUT, conf.ntiles) - val pop_p_rep_data = Bits(OUTPUT, conf.ntiles) - val pop_p_rep_dep = Bits(OUTPUT, conf.ntiles) - val pop_x_init = Bits(OUTPUT, conf.ntiles) - val pop_x_init_data = Bits(OUTPUT, conf.ntiles) - val pop_x_init_dep = Bits(OUTPUT, conf.ntiles) + val push_p_req = Bits(OUTPUT, conf.ln.nTiles) + val pop_p_rep = Bits(OUTPUT, conf.ln.nTiles) + val pop_p_rep_data = Bits(OUTPUT, conf.ln.nTiles) + val pop_p_rep_dep = Bits(OUTPUT, conf.ln.nTiles) + val pop_x_init = Bits(OUTPUT, conf.ln.nTiles) + val pop_x_init_data = Bits(OUTPUT, conf.ln.nTiles) + val pop_x_init_dep = Bits(OUTPUT, conf.ln.nTiles) val send_x_rep_ack = Bool(OUTPUT) } @@ -91,8 +91,8 @@ class XactTracker(id: Int)(implicit conf: UncoreConfiguration) extends Component val state = Reg(resetVal = s_idle) val xact = Reg{ new TransactionInit } val init_tile_id_ = Reg{ Bits() } - val p_rep_count = if (conf.ntiles == 1) UFix(0) else Reg(resetVal = UFix(0, width = log2Up(conf.ntiles))) - val p_req_flags = Reg(resetVal = Bits(0, width = conf.ntiles)) + val p_rep_count = if (conf.ln.nTiles == 1) UFix(0) else Reg(resetVal = UFix(0, width = log2Up(conf.ln.nTiles))) + val p_req_flags = Reg(resetVal = Bits(0, width = conf.ln.nTiles)) val p_rep_tile_id_ = Reg{ Bits() } val x_needs_read = Reg(resetVal = Bool(false)) val x_init_data_needs_write = Reg(resetVal = Bool(false)) @@ -102,16 +102,16 @@ class XactTracker(id: Int)(implicit conf: UncoreConfiguration) extends Component val mem_cnt = Reg(resetVal = UFix(0, width = log2Up(REFILL_CYCLES))) val mem_cnt_next = mem_cnt + UFix(1) val mem_cnt_max = ~UFix(0, width = log2Up(REFILL_CYCLES)) - val p_req_initial_flags = Bits(width = conf.ntiles) + val p_req_initial_flags = Bits(width = conf.ln.nTiles) p_req_initial_flags := Bits(0) - if (conf.ntiles > 1) { + if (conf.ln.nTiles > 1) { // issue self-probes for uncached read xacts to facilitate I$ coherence // TODO: this is hackish; figure out how to do it more systematically val probe_self = co match { case u: CoherencePolicyWithUncached => u.isUncachedReadTransaction(io.alloc_req.bits.xact_init) case _ => Bool(false) } - val myflag = Mux(probe_self, Bits(0), UFixToOH(io.alloc_req.bits.tile_id(log2Up(conf.ntiles)-1,0))) + val myflag = Mux(probe_self, Bits(0), UFixToOH(io.alloc_req.bits.tile_id(log2Up(conf.ln.nTiles)-1,0))) p_req_initial_flags := ~(io.tile_incoherent | myflag) } @@ -120,7 +120,7 @@ class XactTracker(id: Int)(implicit conf: UncoreConfiguration) extends Component io.init_tile_id := init_tile_id_ io.p_rep_tile_id := p_rep_tile_id_ io.tile_xact_id := xact.tile_xact_id - io.sharer_count := UFix(conf.ntiles) // TODO: Broadcast only + io.sharer_count := UFix(conf.ln.nTiles) // TODO: Broadcast only io.x_type := xact.x_type io.mem_req_cmd.valid := Bool(false) @@ -134,13 +134,13 @@ class XactTracker(id: Int)(implicit conf: UncoreConfiguration) extends Component io.probe_req.bits.p_type := co.getProbeRequestType(xact.x_type, UFix(0)) io.probe_req.bits.global_xact_id := UFix(id) io.probe_req.bits.addr := xact.addr - io.push_p_req := Bits(0, width = conf.ntiles) - io.pop_p_rep := Bits(0, width = conf.ntiles) - io.pop_p_rep_data := Bits(0, width = conf.ntiles) - io.pop_p_rep_dep := Bits(0, width = conf.ntiles) - io.pop_x_init := Bits(0, width = conf.ntiles) - io.pop_x_init_data := Bits(0, width = conf.ntiles) - io.pop_x_init_dep := Bits(0, width = conf.ntiles) + io.push_p_req := Bits(0, width = conf.ln.nTiles) + io.pop_p_rep := Bits(0, width = conf.ln.nTiles) + io.pop_p_rep_data := Bits(0, width = conf.ln.nTiles) + io.pop_p_rep_dep := Bits(0, width = conf.ln.nTiles) + io.pop_x_init := Bits(0, width = conf.ln.nTiles) + io.pop_x_init_data := Bits(0, width = conf.ln.nTiles) + io.pop_x_init_dep := Bits(0, width = conf.ln.nTiles) io.send_x_rep_ack := Bool(false) switch (state) { @@ -155,7 +155,7 @@ class XactTracker(id: Int)(implicit conf: UncoreConfiguration) extends Component p_w_mem_cmd_sent := Bool(false) x_w_mem_cmd_sent := Bool(false) io.pop_x_init := UFix(1) << io.alloc_req.bits.tile_id - if(conf.ntiles > 1) { + if(conf.ln.nTiles > 1) { p_rep_count := PopCount(p_req_initial_flags) state := Mux(p_req_initial_flags.orR, s_probe, s_mem) } else state := s_mem @@ -172,7 +172,7 @@ class XactTracker(id: Int)(implicit conf: UncoreConfiguration) extends Component when(io.p_rep_cnt_dec.orR) { val dec = PopCount(io.p_rep_cnt_dec) io.pop_p_rep := io.p_rep_cnt_dec - if(conf.ntiles > 1) p_rep_count := p_rep_count - dec + if(conf.ln.nTiles > 1) p_rep_count := p_rep_count - dec when(p_rep_count === dec) { state := s_mem } @@ -223,16 +223,16 @@ class XactTracker(id: Int)(implicit conf: UncoreConfiguration) extends Component } } -case class UncoreConfiguration(ntiles: Int, tile_id_bits: Int, co: CoherencePolicy) +case class CoherenceHubConfiguration(co: CoherencePolicy, ln: LogicalNetworkConfiguration) -abstract class CoherenceHub(implicit conf: UncoreConfiguration) extends Component { +abstract class CoherenceHub(implicit conf: LogicalNetworkConfiguration) extends Component with MasterCoherenceAgent { val io = new Bundle { - val tiles = Vec(conf.ntiles) { new ioTileLink }.flip + val tiles = Vec(conf.nTiles) { new TileLink }.flip val mem = new ioMem } } -class CoherenceHubNull(implicit conf: UncoreConfiguration) extends CoherenceHub +class CoherenceHubNull(implicit conf: CoherenceHubConfiguration) extends CoherenceHub()(conf.ln) { val co = conf.co.asInstanceOf[ThreeStateIncoherence] @@ -261,24 +261,24 @@ class CoherenceHubNull(implicit conf: UncoreConfiguration) extends CoherenceHub } -class CoherenceHubBroadcast(implicit conf: UncoreConfiguration) extends CoherenceHub +class CoherenceHubBroadcast(implicit conf: CoherenceHubConfiguration) extends CoherenceHub()(conf.ln) { val co = conf.co val trackerList = (0 until NGLOBAL_XACTS).map(new XactTracker(_)) val busy_arr = Vec(NGLOBAL_XACTS){ Bool() } val addr_arr = Vec(NGLOBAL_XACTS){ Bits(width=PADDR_BITS-OFFSET_BITS) } - val init_tile_id_arr = Vec(NGLOBAL_XACTS){ Bits(width=conf.tile_id_bits) } + val init_tile_id_arr = Vec(NGLOBAL_XACTS){ Bits(width=conf.ln.idBits) } val tile_xact_id_arr = Vec(NGLOBAL_XACTS){ Bits(width=TILE_XACT_ID_BITS) } val x_type_arr = Vec(NGLOBAL_XACTS){ Bits(width=X_INIT_TYPE_MAX_BITS) } - val sh_count_arr = Vec(NGLOBAL_XACTS){ Bits(width=conf.tile_id_bits) } + val sh_count_arr = Vec(NGLOBAL_XACTS){ Bits(width=conf.ln.idBits) } val send_x_rep_ack_arr = Vec(NGLOBAL_XACTS){ Bool() } val do_free_arr = Vec(NGLOBAL_XACTS){ Bool() } - val p_rep_cnt_dec_arr = VecBuf(NGLOBAL_XACTS){ Vec(conf.ntiles){ Bool()} } - val p_req_cnt_inc_arr = VecBuf(NGLOBAL_XACTS){ Vec(conf.ntiles){ Bool()} } + val p_rep_cnt_dec_arr = VecBuf(NGLOBAL_XACTS){ Vec(conf.ln.nTiles){ Bool()} } + val p_req_cnt_inc_arr = VecBuf(NGLOBAL_XACTS){ Vec(conf.ln.nTiles){ Bool()} } val sent_x_rep_ack_arr = Vec(NGLOBAL_XACTS){ Bool() } - val p_data_tile_id_arr = Vec(NGLOBAL_XACTS){ Bits(width=conf.tile_id_bits) } + val p_data_tile_id_arr = Vec(NGLOBAL_XACTS){ Bits(width=conf.ln.idBits) } val p_data_valid_arr = Vec(NGLOBAL_XACTS){ Bool() } for( i <- 0 until NGLOBAL_XACTS) { @@ -299,19 +299,19 @@ class CoherenceHubBroadcast(implicit conf: UncoreConfiguration) extends Coherenc t.sent_x_rep_ack := sent_x_rep_ack_arr(i) do_free_arr(i) := Bool(false) sent_x_rep_ack_arr(i) := Bool(false) - p_data_tile_id_arr(i) := Bits(0, width = conf.tile_id_bits) + p_data_tile_id_arr(i) := Bits(0, width = conf.ln.idBits) p_data_valid_arr(i) := Bool(false) - for( j <- 0 until conf.ntiles) { + for( j <- 0 until conf.ln.nTiles) { p_rep_cnt_dec_arr(i)(j) := Bool(false) p_req_cnt_inc_arr(i)(j) := Bool(false) } } - val p_rep_data_dep_list = List.fill(conf.ntiles)((new Queue(NGLOBAL_XACTS)){new TrackerDependency}) // depth must >= NPRIMARY - val x_init_data_dep_list = List.fill(conf.ntiles)((new Queue(NGLOBAL_XACTS)){new TrackerDependency}) // depth should >= NPRIMARY + val p_rep_data_dep_list = List.fill(conf.ln.nTiles)((new Queue(NGLOBAL_XACTS)){new TrackerDependency}) // depth must >= NPRIMARY + val x_init_data_dep_list = List.fill(conf.ln.nTiles)((new Queue(NGLOBAL_XACTS)){new TrackerDependency}) // depth should >= NPRIMARY // Free finished transactions - for( j <- 0 until conf.ntiles ) { + for( j <- 0 until conf.ln.nTiles ) { val finish = io.tiles(j).xact_finish when (finish.valid) { do_free_arr(finish.bits.global_xact_id) := Bool(true) @@ -323,7 +323,7 @@ class CoherenceHubBroadcast(implicit conf: UncoreConfiguration) extends Coherenc // Forward memory responses from mem to tile or arbitrate to ack val mem_idx = io.mem.resp.bits.tag val ack_idx = PriorityEncoder(send_x_rep_ack_arr.toBits) - for( j <- 0 until conf.ntiles ) { + for( j <- 0 until conf.ln.nTiles ) { val rep = io.tiles(j).xact_rep rep.bits.x_type := UFix(0) rep.bits.tile_xact_id := UFix(0) @@ -362,7 +362,7 @@ class CoherenceHubBroadcast(implicit conf: UncoreConfiguration) extends Coherenc io.mem.req_data <> Queue(mem_req_data_arb.io.out) // Handle probe replies, which may or may not have data - for( j <- 0 until conf.ntiles ) { + for( j <- 0 until conf.ln.nTiles ) { val p_rep = io.tiles(j).probe_rep val p_rep_data = io.tiles(j).probe_rep_data val idx = p_rep.bits.global_xact_id @@ -382,10 +382,10 @@ class CoherenceHubBroadcast(implicit conf: UncoreConfiguration) extends Coherenc trackerList(i).io.p_rep_data.valid := io.tiles(trackerList(i).io.p_rep_tile_id).probe_rep_data.valid trackerList(i).io.p_rep_data.bits := io.tiles(trackerList(i).io.p_rep_tile_id).probe_rep_data.bits - trackerList(i).io.p_rep_data_dep.valid := MuxLookup(trackerList(i).io.p_rep_tile_id, p_rep_data_dep_list(0).io.deq.valid, (0 until conf.ntiles).map( j => UFix(j) -> p_rep_data_dep_list(j).io.deq.valid)) - trackerList(i).io.p_rep_data_dep.bits := MuxLookup(trackerList(i).io.p_rep_tile_id, p_rep_data_dep_list(0).io.deq.bits, (0 until conf.ntiles).map( j => UFix(j) -> p_rep_data_dep_list(j).io.deq.bits)) + trackerList(i).io.p_rep_data_dep.valid := MuxLookup(trackerList(i).io.p_rep_tile_id, p_rep_data_dep_list(0).io.deq.valid, (0 until conf.ln.nTiles).map( j => UFix(j) -> p_rep_data_dep_list(j).io.deq.valid)) + trackerList(i).io.p_rep_data_dep.bits := MuxLookup(trackerList(i).io.p_rep_tile_id, p_rep_data_dep_list(0).io.deq.bits, (0 until conf.ln.nTiles).map( j => UFix(j) -> p_rep_data_dep_list(j).io.deq.bits)) - for( j <- 0 until conf.ntiles) { + for( j <- 0 until conf.ln.nTiles) { val p_rep = io.tiles(j).probe_rep p_rep_cnt_dec_arr(i)(j) := p_rep.valid && (p_rep.bits.global_xact_id === UFix(i)) } @@ -393,9 +393,9 @@ class CoherenceHubBroadcast(implicit conf: UncoreConfiguration) extends Coherenc // Nack conflicting transaction init attempts val s_idle :: s_abort_drain :: s_abort_send :: Nil = Enum(3){ UFix() } - val abort_state_arr = Vec(conf.ntiles) { Reg(resetVal = s_idle) } - val want_to_abort_arr = Vec(conf.ntiles) { Bool() } - for( j <- 0 until conf.ntiles ) { + val abort_state_arr = Vec(conf.ln.nTiles) { Reg(resetVal = s_idle) } + val want_to_abort_arr = Vec(conf.ln.nTiles) { Bool() } + for( j <- 0 until conf.ln.nTiles ) { val x_init = io.tiles(j).xact_init val x_init_data = io.tiles(j).xact_init_data val x_abort = io.tiles(j).xact_abort @@ -440,7 +440,7 @@ class CoherenceHubBroadcast(implicit conf: UncoreConfiguration) extends Coherenc // Only one allocation per cycle // Init requests may or may not have data val alloc_arb = (new Arbiter(NGLOBAL_XACTS)) { Bool() } - val init_arb = (new Arbiter(conf.ntiles)) { new TrackerAllocReq } + val init_arb = (new Arbiter(conf.ln.nTiles)) { new TrackerAllocReq } for( i <- 0 until NGLOBAL_XACTS ) { alloc_arb.io.in(i).valid := !trackerList(i).io.busy trackerList(i).io.can_alloc := alloc_arb.io.in(i).ready @@ -449,10 +449,10 @@ class CoherenceHubBroadcast(implicit conf: UncoreConfiguration) extends Coherenc trackerList(i).io.x_init_data.bits := io.tiles(trackerList(i).io.init_tile_id).xact_init_data.bits trackerList(i).io.x_init_data.valid := io.tiles(trackerList(i).io.init_tile_id).xact_init_data.valid - trackerList(i).io.x_init_data_dep.bits := MuxLookup(trackerList(i).io.init_tile_id, x_init_data_dep_list(0).io.deq.bits, (0 until conf.ntiles).map( j => UFix(j) -> x_init_data_dep_list(j).io.deq.bits)) - trackerList(i).io.x_init_data_dep.valid := MuxLookup(trackerList(i).io.init_tile_id, x_init_data_dep_list(0).io.deq.valid, (0 until conf.ntiles).map( j => UFix(j) -> x_init_data_dep_list(j).io.deq.valid)) + trackerList(i).io.x_init_data_dep.bits := MuxLookup(trackerList(i).io.init_tile_id, x_init_data_dep_list(0).io.deq.bits, (0 until conf.ln.nTiles).map( j => UFix(j) -> x_init_data_dep_list(j).io.deq.bits)) + trackerList(i).io.x_init_data_dep.valid := MuxLookup(trackerList(i).io.init_tile_id, x_init_data_dep_list(0).io.deq.valid, (0 until conf.ln.nTiles).map( j => UFix(j) -> x_init_data_dep_list(j).io.deq.valid)) } - for( j <- 0 until conf.ntiles ) { + for( j <- 0 until conf.ln.nTiles ) { val x_init = io.tiles(j).xact_init val x_init_data = io.tiles(j).xact_init_data val x_init_data_dep = x_init_data_dep_list(j).io.deq @@ -473,8 +473,8 @@ class CoherenceHubBroadcast(implicit conf: UncoreConfiguration) extends Coherenc // Handle probe request generation // Must arbitrate for each request port - val p_req_arb_arr = List.fill(conf.ntiles)((new Arbiter(NGLOBAL_XACTS)) { new ProbeRequest() }) - for( j <- 0 until conf.ntiles ) { + val p_req_arb_arr = List.fill(conf.ln.nTiles)((new Arbiter(NGLOBAL_XACTS)) { new ProbeRequest() }) + for( j <- 0 until conf.ln.nTiles ) { for( i <- 0 until NGLOBAL_XACTS ) { val t = trackerList(i).io p_req_arb_arr(j).io.in(i).bits := t.probe_req.bits