NASTI -> TL converter also uses ID mapper
This commit is contained in:
parent
39bee5198d
commit
caa9ca24b9
@ -6,62 +6,62 @@ import uncore.tilelink._
|
|||||||
import uncore.constants._
|
import uncore.constants._
|
||||||
import cde.Parameters
|
import cde.Parameters
|
||||||
|
|
||||||
class NastiIOTileLinkIOIdMapper(implicit val p: Parameters) extends Module
|
class IdMapper(val inIdBits: Int, val outIdBits: Int)
|
||||||
with HasTileLinkParameters with HasNastiParameters {
|
(implicit val p: Parameters) extends Module {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val req = new Bundle {
|
val req = new Bundle {
|
||||||
val valid = Bool(INPUT)
|
val valid = Bool(INPUT)
|
||||||
val ready = Bool(OUTPUT)
|
val ready = Bool(OUTPUT)
|
||||||
val tl_id = UInt(INPUT, tlClientXactIdBits)
|
val in_id = UInt(INPUT, inIdBits)
|
||||||
val nasti_id = UInt(OUTPUT, nastiXIdBits)
|
val out_id = UInt(OUTPUT, outIdBits)
|
||||||
}
|
}
|
||||||
val resp = new Bundle {
|
val resp = new Bundle {
|
||||||
val valid = Bool(INPUT)
|
val valid = Bool(INPUT)
|
||||||
val matches = Bool(OUTPUT)
|
val matches = Bool(OUTPUT)
|
||||||
val nasti_id = UInt(INPUT, nastiXIdBits)
|
val out_id = UInt(INPUT, inIdBits)
|
||||||
val tl_id = UInt(OUTPUT, tlClientXactIdBits)
|
val in_id = UInt(OUTPUT, outIdBits)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val tlMaxXacts = tlMaxClientXacts * tlMaxClientsPerPort
|
val maxInXacts = 1 << inIdBits
|
||||||
|
|
||||||
if (tlClientXactIdBits <= nastiXIdBits) {
|
if (inIdBits <= outIdBits) {
|
||||||
io.req.ready := Bool(true)
|
io.req.ready := Bool(true)
|
||||||
io.req.nasti_id := io.req.tl_id
|
io.req.out_id := io.req.in_id
|
||||||
io.resp.matches := Bool(true)
|
io.resp.matches := Bool(true)
|
||||||
io.resp.tl_id := io.resp.nasti_id
|
io.resp.in_id := io.resp.out_id
|
||||||
} else if (nastiXIdBits <= 2) {
|
} else if (outIdBits <= 2) {
|
||||||
val nQueues = 1 << nastiXIdBits
|
val nQueues = 1 << outIdBits
|
||||||
val entriesPerQueue = (tlMaxXacts - 1) / nQueues + 1
|
val entriesPerQueue = (maxInXacts - 1) / nQueues + 1
|
||||||
val (req_nasti_id, req_nasti_flip) = Counter(io.req.valid && io.req.ready, nQueues)
|
val (req_out_id, req_out_flip) = Counter(io.req.valid && io.req.ready, nQueues)
|
||||||
io.req.ready := Bool(false)
|
io.req.ready := Bool(false)
|
||||||
io.resp.matches := Bool(false)
|
io.resp.matches := Bool(false)
|
||||||
io.resp.tl_id := UInt(0)
|
io.resp.in_id := UInt(0)
|
||||||
io.req.nasti_id := req_nasti_id
|
io.req.out_id := req_out_id
|
||||||
for (i <- 0 until nQueues) {
|
for (i <- 0 until nQueues) {
|
||||||
val queue = Module(new Queue(UInt(width = tlClientXactIdBits), entriesPerQueue))
|
val queue = Module(new Queue(UInt(width = inIdBits), entriesPerQueue))
|
||||||
queue.io.enq.valid := io.req.valid && req_nasti_id === UInt(i)
|
queue.io.enq.valid := io.req.valid && req_out_id === UInt(i)
|
||||||
queue.io.enq.bits := io.req.tl_id
|
queue.io.enq.bits := io.req.in_id
|
||||||
when (req_nasti_id === UInt(i)) { io.req.ready := queue.io.enq.ready }
|
when (req_out_id === UInt(i)) { io.req.ready := queue.io.enq.ready }
|
||||||
|
|
||||||
queue.io.deq.ready := io.resp.valid && io.resp.nasti_id === UInt(i)
|
queue.io.deq.ready := io.resp.valid && io.resp.out_id === UInt(i)
|
||||||
when (io.resp.nasti_id === UInt(i)) {
|
when (io.resp.out_id === UInt(i)) {
|
||||||
io.resp.matches := queue.io.deq.valid
|
io.resp.matches := queue.io.deq.valid
|
||||||
io.resp.tl_id := queue.io.deq.bits
|
io.resp.in_id := queue.io.deq.bits
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val maxNastiId = 1 << nastiXIdBits
|
val maxOutId = 1 << outIdBits
|
||||||
val (req_nasti_id, req_nasti_flip) = Counter(io.req.valid && io.req.ready, maxNastiId)
|
val (req_out_id, req_nasti_flip) = Counter(io.req.valid && io.req.ready, maxOutId)
|
||||||
val roq = Module(new ReorderQueue(
|
val roq = Module(new ReorderQueue(
|
||||||
UInt(width = tlClientXactIdBits), nastiXIdBits, tlMaxXacts))
|
UInt(width = inIdBits), outIdBits, maxInXacts))
|
||||||
roq.io.enq.valid := io.req.valid
|
roq.io.enq.valid := io.req.valid
|
||||||
roq.io.enq.bits.data := io.req.tl_id
|
roq.io.enq.bits.data := io.req.in_id
|
||||||
roq.io.enq.bits.tag := req_nasti_id
|
roq.io.enq.bits.tag := req_out_id
|
||||||
io.req.ready := roq.io.enq.ready
|
io.req.ready := roq.io.enq.ready
|
||||||
io.req.nasti_id := req_nasti_id
|
io.req.out_id := req_out_id
|
||||||
roq.io.deq.valid := io.resp.valid
|
roq.io.deq.valid := io.resp.valid
|
||||||
roq.io.deq.tag := io.resp.nasti_id
|
roq.io.deq.tag := io.resp.out_id
|
||||||
io.resp.tl_id := roq.io.deq.data
|
io.resp.in_id := roq.io.deq.data
|
||||||
io.resp.matches := roq.io.deq.matches
|
io.resp.matches := roq.io.deq.matches
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,8 +109,8 @@ class NastiIOTileLinkIOConverter(implicit p: Parameters) extends TLModule()(p)
|
|||||||
val roq = Module(new ReorderQueue(
|
val roq = Module(new ReorderQueue(
|
||||||
new NastiIOTileLinkIOConverterInfo, nastiRIdBits, tlMaxXacts))
|
new NastiIOTileLinkIOConverterInfo, nastiRIdBits, tlMaxXacts))
|
||||||
|
|
||||||
val get_id_mapper = Module(new NastiIOTileLinkIOIdMapper)
|
val get_id_mapper = Module(new IdMapper(tlClientXactIdBits, nastiXIdBits))
|
||||||
val put_id_mapper = Module(new NastiIOTileLinkIOIdMapper)
|
val put_id_mapper = Module(new IdMapper(tlClientXactIdBits, nastiXIdBits))
|
||||||
|
|
||||||
val get_id_ready = get_id_mapper.io.req.ready
|
val get_id_ready = get_id_mapper.io.req.ready
|
||||||
val put_id_mask = is_subblock || io.tl.acquire.bits.addr_beat === UInt(0)
|
val put_id_mask = is_subblock || io.tl.acquire.bits.addr_beat === UInt(0)
|
||||||
@ -145,19 +145,19 @@ class NastiIOTileLinkIOConverter(implicit p: Parameters) extends TLModule()(p)
|
|||||||
roq.io.deq.tag := io.nasti.r.bits.id
|
roq.io.deq.tag := io.nasti.r.bits.id
|
||||||
|
|
||||||
get_id_mapper.io.req.valid := get_helper.fire(get_id_ready)
|
get_id_mapper.io.req.valid := get_helper.fire(get_id_ready)
|
||||||
get_id_mapper.io.req.tl_id := io.tl.acquire.bits.client_xact_id
|
get_id_mapper.io.req.in_id := io.tl.acquire.bits.client_xact_id
|
||||||
get_id_mapper.io.resp.valid := io.nasti.r.fire() && io.nasti.r.bits.last
|
get_id_mapper.io.resp.valid := io.nasti.r.fire() && io.nasti.r.bits.last
|
||||||
get_id_mapper.io.resp.nasti_id := io.nasti.r.bits.id
|
get_id_mapper.io.resp.out_id := io.nasti.r.bits.id
|
||||||
|
|
||||||
put_id_mapper.io.req.valid := put_helper.fire(put_id_ready, put_id_mask)
|
put_id_mapper.io.req.valid := put_helper.fire(put_id_ready, put_id_mask)
|
||||||
put_id_mapper.io.req.tl_id := io.tl.acquire.bits.client_xact_id
|
put_id_mapper.io.req.in_id := io.tl.acquire.bits.client_xact_id
|
||||||
put_id_mapper.io.resp.valid := io.nasti.b.fire()
|
put_id_mapper.io.resp.valid := io.nasti.b.fire()
|
||||||
put_id_mapper.io.resp.nasti_id := io.nasti.b.bits.id
|
put_id_mapper.io.resp.out_id := io.nasti.b.bits.id
|
||||||
|
|
||||||
// Decompose outgoing TL Acquires into Nasti address and data channels
|
// Decompose outgoing TL Acquires into Nasti address and data channels
|
||||||
io.nasti.ar.valid := get_helper.fire(io.nasti.ar.ready)
|
io.nasti.ar.valid := get_helper.fire(io.nasti.ar.ready)
|
||||||
io.nasti.ar.bits := NastiReadAddressChannel(
|
io.nasti.ar.bits := NastiReadAddressChannel(
|
||||||
id = get_id_mapper.io.req.nasti_id,
|
id = get_id_mapper.io.req.out_id,
|
||||||
addr = io.tl.acquire.bits.full_addr(),
|
addr = io.tl.acquire.bits.full_addr(),
|
||||||
size = Mux(is_subblock,
|
size = Mux(is_subblock,
|
||||||
opSizeToXSize(io.tl.acquire.bits.op_size()),
|
opSizeToXSize(io.tl.acquire.bits.op_size()),
|
||||||
@ -186,14 +186,14 @@ class NastiIOTileLinkIOConverter(implicit p: Parameters) extends TLModule()(p)
|
|||||||
|
|
||||||
io.nasti.aw.valid := put_helper.fire(aw_ready, !w_inflight)
|
io.nasti.aw.valid := put_helper.fire(aw_ready, !w_inflight)
|
||||||
io.nasti.aw.bits := NastiWriteAddressChannel(
|
io.nasti.aw.bits := NastiWriteAddressChannel(
|
||||||
id = put_id_mapper.io.req.nasti_id,
|
id = put_id_mapper.io.req.out_id,
|
||||||
addr = io.tl.acquire.bits.full_addr()| put_offset,
|
addr = io.tl.acquire.bits.full_addr()| put_offset,
|
||||||
size = put_size,
|
size = put_size,
|
||||||
len = Mux(is_multibeat, UInt(tlDataBeats - 1), UInt(0)))
|
len = Mux(is_multibeat, UInt(tlDataBeats - 1), UInt(0)))
|
||||||
|
|
||||||
io.nasti.w.valid := put_helper.fire(io.nasti.w.ready)
|
io.nasti.w.valid := put_helper.fire(io.nasti.w.ready)
|
||||||
io.nasti.w.bits := NastiWriteDataChannel(
|
io.nasti.w.bits := NastiWriteDataChannel(
|
||||||
id = put_id_mapper.io.req.nasti_id,
|
id = put_id_mapper.io.req.out_id,
|
||||||
data = io.tl.acquire.bits.data,
|
data = io.tl.acquire.bits.data,
|
||||||
strb = io.tl.acquire.bits.wmask(),
|
strb = io.tl.acquire.bits.wmask(),
|
||||||
last = tl_wrap_out || (io.tl.acquire.fire() && is_subblock))
|
last = tl_wrap_out || (io.tl.acquire.fire() && is_subblock))
|
||||||
@ -222,7 +222,7 @@ class NastiIOTileLinkIOConverter(implicit p: Parameters) extends TLModule()(p)
|
|||||||
is_builtin_type = Bool(true),
|
is_builtin_type = Bool(true),
|
||||||
g_type = Mux(roq.io.deq.data.subblock,
|
g_type = Mux(roq.io.deq.data.subblock,
|
||||||
Grant.getDataBeatType, Grant.getDataBlockType),
|
Grant.getDataBeatType, Grant.getDataBlockType),
|
||||||
client_xact_id = get_id_mapper.io.resp.tl_id,
|
client_xact_id = get_id_mapper.io.resp.in_id,
|
||||||
manager_xact_id = UInt(0),
|
manager_xact_id = UInt(0),
|
||||||
addr_beat = Mux(roq.io.deq.data.subblock, roq.io.deq.data.addr_beat, tl_cnt_in),
|
addr_beat = Mux(roq.io.deq.data.subblock, roq.io.deq.data.addr_beat, tl_cnt_in),
|
||||||
data = io.nasti.r.bits.data)
|
data = io.nasti.r.bits.data)
|
||||||
@ -237,7 +237,7 @@ class NastiIOTileLinkIOConverter(implicit p: Parameters) extends TLModule()(p)
|
|||||||
gnt_arb.io.in(1).bits := Grant(
|
gnt_arb.io.in(1).bits := Grant(
|
||||||
is_builtin_type = Bool(true),
|
is_builtin_type = Bool(true),
|
||||||
g_type = Grant.putAckType,
|
g_type = Grant.putAckType,
|
||||||
client_xact_id = put_id_mapper.io.resp.tl_id,
|
client_xact_id = put_id_mapper.io.resp.in_id,
|
||||||
manager_xact_id = UInt(0),
|
manager_xact_id = UInt(0),
|
||||||
addr_beat = UInt(0),
|
addr_beat = UInt(0),
|
||||||
data = Bits(0))
|
data = Bits(0))
|
||||||
@ -260,6 +260,7 @@ class TileLinkIONastiIOConverter(implicit p: Parameters) extends TLModule()(p)
|
|||||||
private val blockOffset = tlByteAddrBits + tlBeatAddrBits
|
private val blockOffset = tlByteAddrBits + tlBeatAddrBits
|
||||||
|
|
||||||
val aw_req = Reg(new NastiWriteAddressChannel)
|
val aw_req = Reg(new NastiWriteAddressChannel)
|
||||||
|
val w_tl_id = Reg(io.tl.acquire.bits.client_xact_id)
|
||||||
|
|
||||||
def is_singlebeat(chan: NastiAddressChannel): Bool =
|
def is_singlebeat(chan: NastiAddressChannel): Bool =
|
||||||
chan.len === UInt(0)
|
chan.len === UInt(0)
|
||||||
@ -307,9 +308,12 @@ class TileLinkIONastiIOConverter(implicit p: Parameters) extends TLModule()(p)
|
|||||||
"NASTI write transaction cannot convert to TileLInk")
|
"NASTI write transaction cannot convert to TileLInk")
|
||||||
|
|
||||||
val put_count = Reg(init = UInt(0, tlBeatAddrBits))
|
val put_count = Reg(init = UInt(0, tlBeatAddrBits))
|
||||||
|
val get_id_mapper = Module(new IdMapper(nastiXIdBits, tlClientXactIdBits))
|
||||||
|
val put_id_mapper = Module(new IdMapper(nastiXIdBits, tlClientXactIdBits))
|
||||||
|
|
||||||
when (io.nasti.aw.fire()) {
|
when (io.nasti.aw.fire()) {
|
||||||
aw_req := io.nasti.aw.bits
|
aw_req := io.nasti.aw.bits
|
||||||
|
w_tl_id := put_id_mapper.io.req.out_id
|
||||||
state := s_put
|
state := s_put
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,10 +327,10 @@ class TileLinkIONastiIOConverter(implicit p: Parameters) extends TLModule()(p)
|
|||||||
|
|
||||||
val get_acquire = Mux(is_multibeat(io.nasti.ar.bits),
|
val get_acquire = Mux(is_multibeat(io.nasti.ar.bits),
|
||||||
GetBlock(
|
GetBlock(
|
||||||
client_xact_id = io.nasti.ar.bits.id,
|
client_xact_id = get_id_mapper.io.req.out_id,
|
||||||
addr_block = nasti_addr_block(io.nasti.ar.bits)),
|
addr_block = nasti_addr_block(io.nasti.ar.bits)),
|
||||||
Get(
|
Get(
|
||||||
client_xact_id = io.nasti.ar.bits.id,
|
client_xact_id = get_id_mapper.io.req.out_id,
|
||||||
addr_block = nasti_addr_block(io.nasti.ar.bits),
|
addr_block = nasti_addr_block(io.nasti.ar.bits),
|
||||||
addr_beat = nasti_addr_beat(io.nasti.ar.bits),
|
addr_beat = nasti_addr_beat(io.nasti.ar.bits),
|
||||||
addr_byte = nasti_addr_byte(io.nasti.ar.bits),
|
addr_byte = nasti_addr_byte(io.nasti.ar.bits),
|
||||||
@ -335,39 +339,62 @@ class TileLinkIONastiIOConverter(implicit p: Parameters) extends TLModule()(p)
|
|||||||
|
|
||||||
val put_acquire = Mux(is_multibeat(aw_req),
|
val put_acquire = Mux(is_multibeat(aw_req),
|
||||||
PutBlock(
|
PutBlock(
|
||||||
client_xact_id = aw_req.id,
|
client_xact_id = w_tl_id,
|
||||||
addr_block = nasti_addr_block(aw_req),
|
addr_block = nasti_addr_block(aw_req),
|
||||||
addr_beat = put_count,
|
addr_beat = put_count,
|
||||||
data = io.nasti.w.bits.data,
|
data = io.nasti.w.bits.data,
|
||||||
wmask = Some(io.nasti.w.bits.strb)),
|
wmask = Some(io.nasti.w.bits.strb)),
|
||||||
Put(
|
Put(
|
||||||
client_xact_id = aw_req.id,
|
client_xact_id = w_tl_id,
|
||||||
addr_block = nasti_addr_block(aw_req),
|
addr_block = nasti_addr_block(aw_req),
|
||||||
addr_beat = nasti_addr_beat(aw_req),
|
addr_beat = nasti_addr_beat(aw_req),
|
||||||
data = io.nasti.w.bits.data,
|
data = io.nasti.w.bits.data,
|
||||||
wmask = Some(nasti_wmask(aw_req, io.nasti.w.bits))))
|
wmask = Some(nasti_wmask(aw_req, io.nasti.w.bits))))
|
||||||
|
|
||||||
|
val get_helper = DecoupledHelper(
|
||||||
|
io.nasti.ar.valid,
|
||||||
|
get_id_mapper.io.req.ready,
|
||||||
|
io.tl.acquire.ready)
|
||||||
|
|
||||||
|
get_id_mapper.io.req.valid := get_helper.fire(
|
||||||
|
get_id_mapper.io.req.ready, state === s_idle)
|
||||||
|
get_id_mapper.io.req.in_id := io.nasti.ar.bits.id
|
||||||
|
get_id_mapper.io.resp.out_id := io.tl.grant.bits.client_xact_id
|
||||||
|
get_id_mapper.io.resp.valid := io.nasti.r.fire() && io.nasti.r.bits.last
|
||||||
|
|
||||||
|
val aw_ok = (state === s_idle && !io.nasti.ar.valid)
|
||||||
|
|
||||||
|
put_id_mapper.io.req.valid := aw_ok && io.nasti.aw.valid
|
||||||
|
put_id_mapper.io.req.in_id := io.nasti.aw.bits.id
|
||||||
|
put_id_mapper.io.resp.out_id := io.tl.grant.bits.client_xact_id
|
||||||
|
put_id_mapper.io.resp.valid := io.nasti.b.fire()
|
||||||
|
|
||||||
io.tl.acquire.bits := Mux(state === s_put, put_acquire, get_acquire)
|
io.tl.acquire.bits := Mux(state === s_put, put_acquire, get_acquire)
|
||||||
io.tl.acquire.valid := (state === s_idle && io.nasti.ar.valid) ||
|
io.tl.acquire.valid := get_helper.fire(io.tl.acquire.ready, state === s_idle) ||
|
||||||
(state === s_put && io.nasti.w.valid)
|
(state === s_put && io.nasti.w.valid)
|
||||||
io.nasti.ar.ready := (state === s_idle && io.tl.acquire.ready)
|
|
||||||
io.nasti.aw.ready := (state === s_idle && !io.nasti.ar.valid)
|
io.nasti.ar.ready := get_helper.fire(io.nasti.ar.valid, state === s_idle)
|
||||||
|
io.nasti.aw.ready := aw_ok && put_id_mapper.io.req.ready
|
||||||
io.nasti.w.ready := (state === s_put && io.tl.acquire.ready)
|
io.nasti.w.ready := (state === s_put && io.tl.acquire.ready)
|
||||||
|
|
||||||
val nXacts = tlMaxClientXacts * tlMaxClientsPerPort
|
val nXacts = tlMaxClientXacts * tlMaxClientsPerPort
|
||||||
|
|
||||||
io.nasti.b.valid := io.tl.grant.valid && tl_b_grant(io.tl.grant.bits)
|
io.nasti.b.valid := io.tl.grant.valid && tl_b_grant(io.tl.grant.bits)
|
||||||
io.nasti.b.bits := NastiWriteResponseChannel(
|
io.nasti.b.bits := NastiWriteResponseChannel(
|
||||||
id = io.tl.grant.bits.client_xact_id)
|
id = put_id_mapper.io.req.out_id)
|
||||||
|
|
||||||
|
assert(!io.nasti.b.valid || put_id_mapper.io.resp.matches,
|
||||||
|
"Put ID does not match")
|
||||||
|
|
||||||
io.nasti.r.valid := io.tl.grant.valid && !tl_b_grant(io.tl.grant.bits)
|
io.nasti.r.valid := io.tl.grant.valid && !tl_b_grant(io.tl.grant.bits)
|
||||||
io.nasti.r.bits := NastiReadDataChannel(
|
io.nasti.r.bits := NastiReadDataChannel(
|
||||||
id = io.tl.grant.bits.client_xact_id,
|
id = get_id_mapper.io.req.out_id,
|
||||||
data = io.tl.grant.bits.data,
|
data = io.tl.grant.bits.data,
|
||||||
last = tl_last(io.tl.grant.bits))
|
last = tl_last(io.tl.grant.bits))
|
||||||
|
|
||||||
|
assert(!io.nasti.r.valid || get_id_mapper.io.resp.matches,
|
||||||
|
"Get ID does not match")
|
||||||
|
|
||||||
io.tl.grant.ready := Mux(tl_b_grant(io.tl.grant.bits),
|
io.tl.grant.ready := Mux(tl_b_grant(io.tl.grant.bits),
|
||||||
io.nasti.b.ready, io.nasti.r.ready)
|
io.nasti.b.ready, io.nasti.r.ready)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user