Broadcast hub nears completion. Still does not handle generation/arbitration for decoupled mem reqs.
This commit is contained in:
parent
8ff6e21e3a
commit
082b38d315
@ -33,9 +33,9 @@ class HubMemReq extends Bundle {
|
|||||||
val req_data = (new ioDecoupled) { new MemData() }
|
val req_data = (new ioDecoupled) { new MemData() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class HubProbeRep extends Bundle {
|
class TrackerProbeData extends Bundle {
|
||||||
val reply = (new ioDecoupled) { new ProbeReply }
|
val valid = Bool()
|
||||||
val data_idx = Bits(width = log2up(NTILES))
|
val data_tile_id = Bits(width = log2up(NTILES))
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrackerAllocReq extends Bundle {
|
class TrackerAllocReq extends Bundle {
|
||||||
@ -180,10 +180,9 @@ trait FourStateCoherence extends CoherencePolicy {
|
|||||||
class XactTracker(id: Int) extends Component with CoherencePolicy {
|
class XactTracker(id: Int) extends Component with CoherencePolicy {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val alloc_req = (new ioDecoupled) { new TrackerAllocReq() }
|
val alloc_req = (new ioDecoupled) { new TrackerAllocReq() }
|
||||||
val probe_rep = (new ioDecoupled) { new HubProbeRep() }
|
val probe_data = (new TrackerProbeData).asInput
|
||||||
val can_alloc = Bool(INPUT)
|
val can_alloc = Bool(INPUT)
|
||||||
val xact_finish = Bool(INPUT)
|
val xact_finish = Bool(INPUT)
|
||||||
val p_rep_has_data = Bool(INPUT)
|
|
||||||
val p_rep_cnt_dec = Bits(NTILES, INPUT)
|
val p_rep_cnt_dec = Bits(NTILES, INPUT)
|
||||||
val p_req_cnt_inc = Bits(NTILES, INPUT)
|
val p_req_cnt_inc = Bits(NTILES, INPUT)
|
||||||
val p_rep_data = (new ioDecoupled) { new ProbeReplyData() }
|
val p_rep_data = (new ioDecoupled) { new ProbeReplyData() }
|
||||||
@ -213,7 +212,15 @@ class XactTracker(id: Int) extends Component with CoherencePolicy {
|
|||||||
(t_type === X_WRITE_UNCACHED) -> P_INVALIDATE))
|
(t_type === X_WRITE_UNCACHED) -> P_INVALIDATE))
|
||||||
}
|
}
|
||||||
|
|
||||||
val s_idle :: s_mem_r :: s_mem_w :: s_mem_wr :: s_probe :: s_busy :: Nil = Enum(6){ UFix() }
|
def needsMemRead(t_type: UFix, global_state: UFix): Bool = {
|
||||||
|
(t_type != X_WRITE_UNCACHED)
|
||||||
|
}
|
||||||
|
|
||||||
|
def needsAckRep(t_type: UFix, global_state: UFix): Bool = {
|
||||||
|
(t_type === X_WRITE_UNCACHED)
|
||||||
|
}
|
||||||
|
|
||||||
|
val s_idle :: s_mem :: s_probe :: s_busy :: Nil = Enum(4){ UFix() }
|
||||||
val state = Reg(resetVal = s_idle)
|
val state = Reg(resetVal = s_idle)
|
||||||
val addr_ = Reg{ Bits() }
|
val addr_ = Reg{ Bits() }
|
||||||
val t_type_ = Reg{ Bits() }
|
val t_type_ = Reg{ Bits() }
|
||||||
@ -223,9 +230,10 @@ class XactTracker(id: Int) extends Component with CoherencePolicy {
|
|||||||
val mem_count = Reg(resetVal = UFix(0, width = log2up(REFILL_CYCLES)))
|
val mem_count = Reg(resetVal = UFix(0, width = log2up(REFILL_CYCLES)))
|
||||||
val p_rep_count = Reg(resetVal = UFix(0, width = log2up(NTILES)))
|
val p_rep_count = Reg(resetVal = UFix(0, width = log2up(NTILES)))
|
||||||
val p_req_flags = Reg(resetVal = UFix(0, width = NTILES))
|
val p_req_flags = Reg(resetVal = UFix(0, width = NTILES))
|
||||||
val p_rep_data_idx_ = Reg{ Bits() }
|
val p_rep_tile_id_ = Reg{ Bits() }
|
||||||
val x_init_data_needs_wb = Reg{ Bool() }
|
val x_needs_read = Reg{ Bool() }
|
||||||
val p_rep_data_needs_wb = Reg{ Bool() }
|
val x_init_data_needs_write = Reg{ Bool() }
|
||||||
|
val p_rep_data_needs_write = Reg{ Bool() }
|
||||||
|
|
||||||
io.busy := state != s_idle
|
io.busy := state != s_idle
|
||||||
io.addr := addr_
|
io.addr := addr_
|
||||||
@ -235,15 +243,17 @@ class XactTracker(id: Int) extends Component with CoherencePolicy {
|
|||||||
io.t_type := t_type_
|
io.t_type := t_type_
|
||||||
|
|
||||||
io.mem_req.valid := Bool(false)
|
io.mem_req.valid := Bool(false)
|
||||||
io.mem_req.bits.req_cmd.bits.rw := state === s_mem_w || state === s_mem_wr
|
io.mem_req.bits.req_cmd.valid := Bool(false)
|
||||||
|
io.mem_req.bits.req_cmd.bits.rw := Bool(false)
|
||||||
io.mem_req.bits.req_cmd.bits.addr := addr_
|
io.mem_req.bits.req_cmd.bits.addr := addr_
|
||||||
io.mem_req.bits.req_cmd.bits.tag := UFix(id)
|
io.mem_req.bits.req_cmd.bits.tag := UFix(id)
|
||||||
|
io.mem_req.bits.req_data.valid := Bool(false)
|
||||||
|
io.mem_req.bits.req_data.bits.data := UFix(0)
|
||||||
// := io.mem.ready //sent mem req
|
// := io.mem.ready //sent mem req
|
||||||
io.probe_req.valid := Bool(false)
|
io.probe_req.valid := Bool(false)
|
||||||
io.probe_req.bits.p_type := sendProbeReqType(t_type_, UFix(0))
|
io.probe_req.bits.p_type := sendProbeReqType(t_type_, UFix(0))
|
||||||
io.probe_req.bits.global_xact_id := UFix(id)
|
io.probe_req.bits.global_xact_id := UFix(id)
|
||||||
io.probe_req.bits.address := addr_
|
io.probe_req.bits.address := addr_
|
||||||
// := io.probe_req.ready //got through arbiter ---- p_rep_dec_arr
|
|
||||||
io.push_p_req := Bits(0, width = NTILES)
|
io.push_p_req := Bits(0, width = NTILES)
|
||||||
io.pop_p_rep := Bits(0, width = NTILES)
|
io.pop_p_rep := Bits(0, width = NTILES)
|
||||||
io.pop_p_rep_data := Bits(0, width = NTILES)
|
io.pop_p_rep_data := Bits(0, width = NTILES)
|
||||||
@ -258,32 +268,14 @@ class XactTracker(id: Int) extends Component with CoherencePolicy {
|
|||||||
t_type_ := io.alloc_req.bits.xact_init.t_type
|
t_type_ := io.alloc_req.bits.xact_init.t_type
|
||||||
init_tile_id_ := io.alloc_req.bits.init_tile_id
|
init_tile_id_ := io.alloc_req.bits.init_tile_id
|
||||||
tile_xact_id_ := io.alloc_req.bits.xact_init.tile_xact_id
|
tile_xact_id_ := io.alloc_req.bits.xact_init.tile_xact_id
|
||||||
x_init_data_needs_wb := io.alloc_req.bits.xact_init.has_data
|
x_init_data_needs_write := io.alloc_req.bits.xact_init.has_data
|
||||||
|
x_needs_read := needsMemRead(io.alloc_req.bits.xact_init.t_type, UFix(0))
|
||||||
p_rep_count := UFix(NTILES)
|
p_rep_count := UFix(NTILES)
|
||||||
p_req_flags := ~Bits(0, width = NTILES)
|
p_req_flags := ~Bits(0, width = NTILES)
|
||||||
state := s_probe
|
state := s_probe
|
||||||
io.pop_x_init := Bool(true)
|
io.pop_x_init := Bool(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(s_mem_r) {
|
|
||||||
io.mem_req.valid := Bool(true)
|
|
||||||
when(io.mem_req.ready) { state := s_busy }
|
|
||||||
}
|
|
||||||
is(s_mem_w) {
|
|
||||||
io.mem_req.valid := Bool(true)
|
|
||||||
when(io.mem_req.ready) { state := s_busy }
|
|
||||||
}
|
|
||||||
is(s_mem_wr) {
|
|
||||||
when(io.probe_rep.bits.reply.bits.has_data) {
|
|
||||||
//io.pop_p_rep(p_rep_data_idx) := io.mem_req_rdy
|
|
||||||
//io.pop_p_rep_data(p_rep_data_idx) := io.mem_req_rdy //TODO
|
|
||||||
} . otherwise {
|
|
||||||
//io.pop_x_init := io.mem_req_rdy
|
|
||||||
//io.pop_x_init_data := io.mem_req_rdy
|
|
||||||
}
|
|
||||||
io.mem_req.valid := Bool(true)
|
|
||||||
when(io.mem_req.ready) { state := s_mem_r }
|
|
||||||
}
|
|
||||||
is(s_probe) {
|
is(s_probe) {
|
||||||
when(p_req_flags.orR) {
|
when(p_req_flags.orR) {
|
||||||
io.push_p_req := p_req_flags
|
io.push_p_req := p_req_flags
|
||||||
@ -292,22 +284,55 @@ class XactTracker(id: Int) extends Component with CoherencePolicy {
|
|||||||
when(io.p_req_cnt_inc.orR) {
|
when(io.p_req_cnt_inc.orR) {
|
||||||
p_req_flags := p_req_flags & ~io.p_req_cnt_inc // unflag sent reqs
|
p_req_flags := p_req_flags & ~io.p_req_cnt_inc // unflag sent reqs
|
||||||
}
|
}
|
||||||
val p_rep_has_data = Bool(INPUT)
|
|
||||||
val p_rep_data_idx = Bits(log2up(NTILES), INPUT)
|
|
||||||
val p_rep_cnt_dec = Bits(NTILES, INPUT)
|
|
||||||
when(io.p_rep_cnt_dec.orR) {
|
when(io.p_rep_cnt_dec.orR) {
|
||||||
val p_rep_count_next = p_rep_count - PopCount(io.p_rep_cnt_dec)
|
val p_rep_count_next = p_rep_count - PopCount(io.p_rep_cnt_dec)
|
||||||
p_rep_count := p_rep_count_next
|
p_rep_count := p_rep_count_next
|
||||||
when(p_rep_count_next === UFix(0)) {
|
when(p_rep_count_next === UFix(0)) {
|
||||||
state := s_busy //TODO: XXXXXXXXXX
|
state := s_mem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when(p_rep_has_data) {
|
when(io.probe_data.valid) {
|
||||||
p_rep_data_needs_wb := Bool(true)
|
p_rep_data_needs_write := Bool(true)
|
||||||
p_rep_data_idx_ := p_rep_data_idx
|
p_rep_tile_id_ := io.p_rep_tile_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(s_busy) {
|
is(s_mem) {
|
||||||
|
when(x_init_data_needs_write) {
|
||||||
|
//io.mem_req.valid := //?TODO ??? || io.x_init_data.valid
|
||||||
|
//io.mem_req.bits.req_cmd.valid := // TODO ???
|
||||||
|
io.mem_req.bits.req_cmd.bits.rw := Bool(true)
|
||||||
|
io.mem_req.bits.req_data <> io.x_init_data
|
||||||
|
when(io.mem_req.ready && io.mem_req.bits.req_cmd.ready) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
when(io.mem_req.ready && io.mem_req.bits.req_data.ready) {
|
||||||
|
io.pop_x_init_data := Bool(true)
|
||||||
|
//TODO: count with mem_count somehow
|
||||||
|
}
|
||||||
|
} . elsewhen (p_rep_data_needs_write) {
|
||||||
|
//io.mem_req.valid := //TODO ??? || io.p_rep_data.valid
|
||||||
|
//io.mem_req.bits.req_cmd.valid := //TODO ???
|
||||||
|
io.mem_req.bits.req_cmd.bits.rw := Bool(true)
|
||||||
|
io.mem_req.bits.req_data <> io.p_rep_data
|
||||||
|
when(io.mem_req.ready && io.mem_req.bits.req_cmd.ready) {
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
when(io.mem_req.ready && io.mem_req.bits.req_data.ready) {
|
||||||
|
io.pop_p_rep_data := Bool(true)
|
||||||
|
//TODO: count with mem_count somehow
|
||||||
|
}
|
||||||
|
} . elsewhen (x_needs_read) {
|
||||||
|
io.mem_req.valid := Bool(true)
|
||||||
|
io.mem_req.bits.req_cmd.valid := Bool(true)
|
||||||
|
when(io.mem_req.ready && io.mem_req.bits.req_cmd.ready) {
|
||||||
|
x_needs_read := Bool(false)
|
||||||
|
}
|
||||||
|
} . otherwise {
|
||||||
|
io.send_x_rep_ack := needsAckRep(t_type_, UFix(0))
|
||||||
|
state := s_busy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is(s_busy) { // Nothing left to do but wait for transaction to complete
|
||||||
when (io.xact_finish) {
|
when (io.xact_finish) {
|
||||||
state := s_idle
|
state := s_idle
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user