Added aborted data dequeueing state machine for BroadcastHub
This commit is contained in:
parent
5c66a6699c
commit
950b5cd900
@ -240,7 +240,8 @@ class XactTracker(id: Int) extends Component with FourStateCoherence {
|
|||||||
req_cmd.valid := !cmd_sent
|
req_cmd.valid := !cmd_sent
|
||||||
req_cmd.bits.rw := Bool(true)
|
req_cmd.bits.rw := Bool(true)
|
||||||
data.ready := req_data.ready
|
data.ready := req_data.ready
|
||||||
req_data <> data
|
req_data.bits := data.bits
|
||||||
|
req_data.valid := data.valid
|
||||||
lock := Bool(true)
|
lock := Bool(true)
|
||||||
when(req_cmd.ready && req_cmd.valid) {
|
when(req_cmd.ready && req_cmd.valid) {
|
||||||
cmd_sent := Bool(true)
|
cmd_sent := Bool(true)
|
||||||
@ -521,23 +522,51 @@ class CoherenceHubBroadcast extends CoherenceHub with FourStateCoherence{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nack conflicting transaction init attempts
|
// Nack conflicting transaction init attempts
|
||||||
val aborting = Bits(0, width = NTILES)
|
val s_idle :: s_abort_drain :: s_abort_send :: s_abort_complete :: Nil = Enum(4){ UFix() }
|
||||||
|
val abort_state_arr = Vec(NTILES) { Reg(resetVal = s_idle) }
|
||||||
|
val want_to_abort_arr = Vec(NTILES) { Wire() { Bool()} }
|
||||||
for( j <- 0 until NTILES ) {
|
for( j <- 0 until NTILES ) {
|
||||||
val x_init = io.tiles(j).xact_init
|
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
|
val x_abort = io.tiles(j).xact_abort
|
||||||
val conflicts = Bits(width = NGLOBAL_XACTS)
|
val conflicts = Bits(width = NGLOBAL_XACTS)
|
||||||
for( i <- 0 until NGLOBAL_XACTS) {
|
for( i <- 0 until NGLOBAL_XACTS) {
|
||||||
val t = trackerList(i).io
|
val t = trackerList(i).io
|
||||||
conflicts(UFix(i), t.busy && coherenceConflict(t.addr, x_init.bits.address) &&
|
conflicts(UFix(i), t.busy && x_init.valid && coherenceConflict(t.addr, x_init.bits.address))
|
||||||
!(transactionInitHasData(x_init.bits) && (UFix(j) === t.init_tile_id)))
|
|
||||||
// Don't abort writebacks stalled on mem.
|
|
||||||
// TODO: This assumes overlapped writeback init reqs to
|
|
||||||
// the same addr will never be issued; is this ok?
|
|
||||||
}
|
}
|
||||||
x_abort.bits.tile_xact_id := x_init.bits.tile_xact_id
|
x_abort.bits.tile_xact_id := x_init.bits.tile_xact_id
|
||||||
val want_to_abort = conflicts.orR || busy_arr.toBits.andR
|
val abort_cnt = Reg(resetVal = UFix(0, width = log2up(REFILL_CYCLES)))
|
||||||
x_abort.valid := want_to_abort && x_init.valid
|
want_to_abort_arr(j) := conflicts.orR || busy_arr.toBits.andR
|
||||||
aborting.bitSet(UFix(j), want_to_abort && x_abort.ready)
|
|
||||||
|
x_abort.valid := Bool(false)
|
||||||
|
switch(abort_state_arr(j)) {
|
||||||
|
is(s_idle) {
|
||||||
|
when(want_to_abort_arr(j)) {
|
||||||
|
when(transactionInitHasData(x_init.bits)) {
|
||||||
|
abort_state_arr(j) := s_abort_drain
|
||||||
|
} . otherwise {
|
||||||
|
abort_state_arr(j) := s_abort_send
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is(s_abort_drain) { // raises x_init_data.ready below
|
||||||
|
when(x_init_data.valid) {
|
||||||
|
abort_cnt := abort_cnt + UFix(1)
|
||||||
|
}
|
||||||
|
when(abort_cnt === ~UFix(0, width = log2up(REFILL_CYCLES))) {
|
||||||
|
abort_state_arr(j) := s_abort_send
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is(s_abort_send) { // nothing is dequeued for now
|
||||||
|
x_abort.valid := Bool(true)
|
||||||
|
when(x_abort.ready) {
|
||||||
|
abort_state_arr(j) := s_abort_complete
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is(s_abort_complete) { // raises x_init.ready below
|
||||||
|
abort_state_arr(j) := s_idle
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle transaction initiation requests
|
// Handle transaction initiation requests
|
||||||
@ -557,15 +586,14 @@ class CoherenceHubBroadcast extends CoherenceHub with FourStateCoherence{
|
|||||||
for( j <- 0 until NTILES ) {
|
for( j <- 0 until NTILES ) {
|
||||||
val x_init = io.tiles(j).xact_init
|
val x_init = io.tiles(j).xact_init
|
||||||
val x_init_data = io.tiles(j).xact_init_data
|
val x_init_data = io.tiles(j).xact_init_data
|
||||||
init_arb.io.in(j).valid := x_init.valid
|
init_arb.io.in(j).valid := (abort_state_arr(j) === s_idle) && !want_to_abort_arr(j) && x_init.valid
|
||||||
init_arb.io.in(j).bits.xact_init := x_init.bits
|
init_arb.io.in(j).bits.xact_init := x_init.bits
|
||||||
init_arb.io.in(j).bits.tile_id := UFix(j)
|
init_arb.io.in(j).bits.tile_id := UFix(j)
|
||||||
x_init.ready := aborting(j) || foldR(trackerList.map(_.io.pop_x_init && init_arb.io.out.bits.tile_id === UFix(j)))(_||_)
|
x_init.ready := (abort_state_arr(j) === s_abort_complete) || foldR(trackerList.map(_.io.pop_x_init && init_arb.io.out.bits.tile_id === UFix(j)))(_||_)
|
||||||
x_init_data.ready := aborting(j) || foldR(trackerList.map(_.io.pop_x_init_data && init_arb.io.out.bits.tile_id === UFix(j)))(_||_)
|
x_init_data.ready := (abort_state_arr(j) === s_abort_drain) || foldR(trackerList.map(_.io.pop_x_init_data && init_arb.io.out.bits.tile_id === UFix(j)))(_||_)
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc_arb.io.out.ready := init_arb.io.out.valid && !busy_arr.toBits.andR &&
|
alloc_arb.io.out.ready := init_arb.io.out.valid
|
||||||
!foldR(trackerList.map(t => t.io.busy && coherenceConflict(t.io.addr, init_arb.io.out.bits.xact_init.address)))(_||_)
|
|
||||||
|
|
||||||
// Handle probe request generation
|
// Handle probe request generation
|
||||||
// Must arbitrate for each request port
|
// Must arbitrate for each request port
|
||||||
|
Loading…
Reference in New Issue
Block a user