fix TileLinkWidthAdapter
This commit is contained in:
parent
324cabc494
commit
f421e2ab11
@ -756,7 +756,7 @@ object TileLinkWidthAdapter {
|
|||||||
widener.io.in <> in
|
widener.io.in <> in
|
||||||
out <> widener.io.out
|
out <> widener.io.out
|
||||||
} else if (out.tlDataBits < in.tlDataBits) {
|
} else if (out.tlDataBits < in.tlDataBits) {
|
||||||
val narrower = Module(new TileLinkIOWidener(in.p(TLId), out.p(TLId)))
|
val narrower = Module(new TileLinkIONarrower(in.p(TLId), out.p(TLId)))
|
||||||
narrower.io.in <> in
|
narrower.io.in <> in
|
||||||
out <> narrower.io.out
|
out <> narrower.io.out
|
||||||
} else {
|
} else {
|
||||||
@ -961,9 +961,9 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
val outerMaxClients = outerParams.maxClientsPerPort
|
val outerMaxClients = outerParams.maxClientsPerPort
|
||||||
val outerIdBits = log2Up(outerParams.maxClientXacts * outerMaxClients)
|
val outerIdBits = log2Up(outerParams.maxClientXacts * outerMaxClients)
|
||||||
|
|
||||||
require(outerDataBeats >= innerDataBeats)
|
require(outerDataBeats > innerDataBeats)
|
||||||
require(outerDataBeats % innerDataBeats == 0)
|
require(outerDataBeats % innerDataBeats == 0)
|
||||||
require(outerDataBits <= innerDataBits)
|
require(outerDataBits < innerDataBits)
|
||||||
require(outerDataBits * outerDataBeats == innerDataBits * innerDataBeats)
|
require(outerDataBits * outerDataBeats == innerDataBits * innerDataBeats)
|
||||||
|
|
||||||
val factor = outerDataBeats / innerDataBeats
|
val factor = outerDataBeats / innerDataBeats
|
||||||
@ -973,166 +973,164 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
val out = new ClientUncachedTileLinkIO()(p.alterPartial({case TLId => outerTLId}))
|
val out = new ClientUncachedTileLinkIO()(p.alterPartial({case TLId => outerTLId}))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (factor > 1) {
|
val iacq = io.in.acquire.bits
|
||||||
val iacq = io.in.acquire.bits
|
val ognt = io.out.grant.bits
|
||||||
val ognt = io.out.grant.bits
|
|
||||||
|
|
||||||
val stretch = iacq.a_type === Acquire.putBlockType
|
val stretch = iacq.a_type === Acquire.putBlockType
|
||||||
val shrink = iacq.a_type === Acquire.getBlockType
|
val shrink = iacq.a_type === Acquire.getBlockType
|
||||||
val smallput = iacq.a_type === Acquire.putType
|
val smallput = iacq.a_type === Acquire.putType
|
||||||
val smallget = iacq.a_type === Acquire.getType
|
val smallget = iacq.a_type === Acquire.getType
|
||||||
|
|
||||||
val acq_data_buffer = Reg(UInt(width = innerDataBits))
|
val acq_data_buffer = Reg(UInt(width = innerDataBits))
|
||||||
val acq_wmask_buffer = Reg(UInt(width = innerWriteMaskBits))
|
val acq_wmask_buffer = Reg(UInt(width = innerWriteMaskBits))
|
||||||
val acq_client_id = Reg(iacq.client_xact_id)
|
val acq_client_id = Reg(iacq.client_xact_id)
|
||||||
val acq_addr_block = Reg(iacq.addr_block)
|
val acq_addr_block = Reg(iacq.addr_block)
|
||||||
val acq_addr_beat = Reg(iacq.addr_beat)
|
val acq_addr_beat = Reg(iacq.addr_beat)
|
||||||
val oacq_ctr = Counter(factor)
|
val oacq_ctr = Counter(factor)
|
||||||
|
|
||||||
val outer_beat_addr = iacq.full_addr()(outerBlockOffset - 1, outerByteAddrBits)
|
val outer_beat_addr = iacq.full_addr()(outerBlockOffset - 1, outerByteAddrBits)
|
||||||
val outer_byte_addr = iacq.full_addr()(outerByteAddrBits - 1, 0)
|
val outer_byte_addr = iacq.full_addr()(outerByteAddrBits - 1, 0)
|
||||||
|
|
||||||
val mask_chunks = Vec.tabulate(factor) { i =>
|
val mask_chunks = Vec.tabulate(factor) { i =>
|
||||||
val lsb = i * outerWriteMaskBits
|
val lsb = i * outerWriteMaskBits
|
||||||
val msb = (i + 1) * outerWriteMaskBits - 1
|
val msb = (i + 1) * outerWriteMaskBits - 1
|
||||||
iacq.wmask()(msb, lsb)
|
iacq.wmask()(msb, lsb)
|
||||||
|
}
|
||||||
|
|
||||||
|
val data_chunks = Vec.tabulate(factor) { i =>
|
||||||
|
val lsb = i * outerDataBits
|
||||||
|
val msb = (i + 1) * outerDataBits - 1
|
||||||
|
iacq.data(msb, lsb)
|
||||||
|
}
|
||||||
|
|
||||||
|
val beat_sel = Cat(mask_chunks.map(mask => mask.orR).reverse)
|
||||||
|
|
||||||
|
val smallput_data = Mux1H(beat_sel, data_chunks)
|
||||||
|
val smallput_wmask = Mux1H(beat_sel, mask_chunks)
|
||||||
|
val smallput_beat = Cat(iacq.addr_beat, PriorityEncoder(beat_sel))
|
||||||
|
|
||||||
|
assert(!io.in.acquire.valid || !smallput || PopCount(beat_sel) <= UInt(1),
|
||||||
|
"Can't perform Put wider than outer width")
|
||||||
|
|
||||||
|
val read_size_ok = MuxLookup(iacq.op_size(), Bool(false), Seq(
|
||||||
|
MT_B -> Bool(true),
|
||||||
|
MT_BU -> Bool(true),
|
||||||
|
MT_H -> Bool(outerDataBits >= 16),
|
||||||
|
MT_HU -> Bool(outerDataBits >= 16),
|
||||||
|
MT_W -> Bool(outerDataBits >= 32),
|
||||||
|
MT_WU -> Bool(outerDataBits >= 32),
|
||||||
|
MT_D -> Bool(outerDataBits >= 64),
|
||||||
|
MT_Q -> Bool(false)))
|
||||||
|
|
||||||
|
assert(!io.in.acquire.valid || !smallget || read_size_ok,
|
||||||
|
"Can't perform Get wider than outer width")
|
||||||
|
|
||||||
|
val outerConfig = p.alterPartial({ case TLId => outerTLId })
|
||||||
|
val innerConfig = p.alterPartial({ case TLId => innerTLId })
|
||||||
|
|
||||||
|
val get_block_acquire = GetBlock(
|
||||||
|
client_xact_id = iacq.client_xact_id,
|
||||||
|
addr_block = iacq.addr_block,
|
||||||
|
alloc = iacq.allocate())(outerConfig)
|
||||||
|
|
||||||
|
val put_block_acquire = PutBlock(
|
||||||
|
client_xact_id = acq_client_id,
|
||||||
|
addr_block = acq_addr_block,
|
||||||
|
addr_beat = if (factor > 1)
|
||||||
|
Cat(acq_addr_beat, oacq_ctr.value)
|
||||||
|
else acq_addr_beat,
|
||||||
|
data = acq_data_buffer(outerDataBits - 1, 0),
|
||||||
|
wmask = acq_wmask_buffer(outerWriteMaskBits - 1, 0))(outerConfig)
|
||||||
|
|
||||||
|
val get_acquire = Get(
|
||||||
|
client_xact_id = iacq.client_xact_id,
|
||||||
|
addr_block = iacq.addr_block,
|
||||||
|
addr_beat = outer_beat_addr,
|
||||||
|
addr_byte = outer_byte_addr,
|
||||||
|
operand_size = iacq.op_size(),
|
||||||
|
alloc = iacq.allocate())(outerConfig)
|
||||||
|
|
||||||
|
val put_acquire = Put(
|
||||||
|
client_xact_id = iacq.client_xact_id,
|
||||||
|
addr_block = iacq.addr_block,
|
||||||
|
addr_beat = smallput_beat,
|
||||||
|
data = smallput_data,
|
||||||
|
wmask = Some(smallput_wmask))(outerConfig)
|
||||||
|
|
||||||
|
val sending_put = Reg(init = Bool(false))
|
||||||
|
|
||||||
|
val pass_valid = io.in.acquire.valid && !stretch
|
||||||
|
|
||||||
|
io.out.acquire.bits := MuxBundle(Wire(io.out.acquire.bits, init=iacq), Seq(
|
||||||
|
(sending_put, put_block_acquire),
|
||||||
|
(shrink, get_block_acquire),
|
||||||
|
(smallput, put_acquire),
|
||||||
|
(smallget, get_acquire)))
|
||||||
|
io.out.acquire.valid := sending_put || pass_valid
|
||||||
|
io.in.acquire.ready := !sending_put && (stretch || io.out.acquire.ready)
|
||||||
|
|
||||||
|
when (io.in.acquire.fire() && stretch) {
|
||||||
|
acq_data_buffer := iacq.data
|
||||||
|
acq_wmask_buffer := iacq.wmask()
|
||||||
|
acq_client_id := iacq.client_xact_id
|
||||||
|
acq_addr_block := iacq.addr_block
|
||||||
|
acq_addr_beat := iacq.addr_beat
|
||||||
|
sending_put := Bool(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
when (sending_put && io.out.acquire.ready) {
|
||||||
|
acq_data_buffer := acq_data_buffer >> outerDataBits
|
||||||
|
acq_wmask_buffer := acq_wmask_buffer >> outerWriteMaskBits
|
||||||
|
when (oacq_ctr.inc()) { sending_put := Bool(false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val ognt_block = ognt.hasMultibeatData()
|
||||||
|
val gnt_data_buffer = Reg(Vec(factor, UInt(width = outerDataBits)))
|
||||||
|
val gnt_client_id = Reg(ognt.client_xact_id)
|
||||||
|
val gnt_manager_id = Reg(ognt.manager_xact_id)
|
||||||
|
|
||||||
|
val ignt_ctr = Counter(innerDataBeats)
|
||||||
|
val ognt_ctr = Counter(factor)
|
||||||
|
val sending_get = Reg(init = Bool(false))
|
||||||
|
|
||||||
|
val get_block_grant = Grant(
|
||||||
|
is_builtin_type = Bool(true),
|
||||||
|
g_type = Grant.getDataBlockType,
|
||||||
|
client_xact_id = gnt_client_id,
|
||||||
|
manager_xact_id = gnt_manager_id,
|
||||||
|
addr_beat = ignt_ctr.value,
|
||||||
|
data = gnt_data_buffer.toBits)(innerConfig)
|
||||||
|
|
||||||
|
val smallget_grant = ognt.g_type === Grant.getDataBeatType
|
||||||
|
|
||||||
|
val get_grant = Grant(
|
||||||
|
is_builtin_type = Bool(true),
|
||||||
|
g_type = Grant.getDataBeatType,
|
||||||
|
client_xact_id = ognt.client_xact_id,
|
||||||
|
manager_xact_id = ognt.manager_xact_id,
|
||||||
|
addr_beat = ognt.addr_beat >> UInt(log2Up(factor)),
|
||||||
|
data = Fill(factor, ognt.data))(innerConfig)
|
||||||
|
|
||||||
|
io.in.grant.valid := sending_get || (io.out.grant.valid && !ognt_block)
|
||||||
|
io.out.grant.ready := !sending_get && (ognt_block || io.in.grant.ready)
|
||||||
|
|
||||||
|
io.in.grant.bits := MuxBundle(Wire(io.in.grant.bits, init=ognt), Seq(
|
||||||
|
sending_get -> get_block_grant,
|
||||||
|
smallget_grant -> get_grant))
|
||||||
|
|
||||||
|
when (io.out.grant.valid && ognt_block && !sending_get) {
|
||||||
|
gnt_data_buffer(ognt_ctr.value) := ognt.data
|
||||||
|
when (ognt_ctr.inc()) {
|
||||||
|
gnt_client_id := ognt.client_xact_id
|
||||||
|
gnt_manager_id := ognt.manager_xact_id
|
||||||
|
sending_get := Bool(true)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val data_chunks = Vec.tabulate(factor) { i =>
|
when (io.in.grant.ready && sending_get) {
|
||||||
val lsb = i * outerDataBits
|
ignt_ctr.inc()
|
||||||
val msb = (i + 1) * outerDataBits - 1
|
sending_get := Bool(false)
|
||||||
iacq.data(msb, lsb)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val beat_sel = Cat(mask_chunks.map(mask => mask.orR).reverse)
|
|
||||||
|
|
||||||
val smallput_data = Mux1H(beat_sel, data_chunks)
|
|
||||||
val smallput_wmask = Mux1H(beat_sel, mask_chunks)
|
|
||||||
val smallput_beat = Cat(iacq.addr_beat, PriorityEncoder(beat_sel))
|
|
||||||
|
|
||||||
assert(!io.in.acquire.valid || !smallput || PopCount(beat_sel) <= UInt(1),
|
|
||||||
"Can't perform Put wider than outer width")
|
|
||||||
|
|
||||||
val read_size_ok = MuxLookup(iacq.op_size(), Bool(false), Seq(
|
|
||||||
MT_B -> Bool(true),
|
|
||||||
MT_BU -> Bool(true),
|
|
||||||
MT_H -> Bool(outerDataBits >= 16),
|
|
||||||
MT_HU -> Bool(outerDataBits >= 16),
|
|
||||||
MT_W -> Bool(outerDataBits >= 32),
|
|
||||||
MT_WU -> Bool(outerDataBits >= 32),
|
|
||||||
MT_D -> Bool(outerDataBits >= 64),
|
|
||||||
MT_Q -> Bool(false)))
|
|
||||||
|
|
||||||
assert(!io.in.acquire.valid || !smallget || read_size_ok,
|
|
||||||
"Can't perform Get wider than outer width")
|
|
||||||
|
|
||||||
val outerConfig = p.alterPartial({ case TLId => outerTLId })
|
|
||||||
val innerConfig = p.alterPartial({ case TLId => innerTLId })
|
|
||||||
|
|
||||||
val get_block_acquire = GetBlock(
|
|
||||||
client_xact_id = iacq.client_xact_id,
|
|
||||||
addr_block = iacq.addr_block,
|
|
||||||
alloc = iacq.allocate())(outerConfig)
|
|
||||||
|
|
||||||
val put_block_acquire = PutBlock(
|
|
||||||
client_xact_id = acq_client_id,
|
|
||||||
addr_block = acq_addr_block,
|
|
||||||
addr_beat = if (factor > 1)
|
|
||||||
Cat(acq_addr_beat, oacq_ctr.value)
|
|
||||||
else acq_addr_beat,
|
|
||||||
data = acq_data_buffer(outerDataBits - 1, 0),
|
|
||||||
wmask = acq_wmask_buffer(outerWriteMaskBits - 1, 0))(outerConfig)
|
|
||||||
|
|
||||||
val get_acquire = Get(
|
|
||||||
client_xact_id = iacq.client_xact_id,
|
|
||||||
addr_block = iacq.addr_block,
|
|
||||||
addr_beat = outer_beat_addr,
|
|
||||||
addr_byte = outer_byte_addr,
|
|
||||||
operand_size = iacq.op_size(),
|
|
||||||
alloc = iacq.allocate())(outerConfig)
|
|
||||||
|
|
||||||
val put_acquire = Put(
|
|
||||||
client_xact_id = iacq.client_xact_id,
|
|
||||||
addr_block = iacq.addr_block,
|
|
||||||
addr_beat = smallput_beat,
|
|
||||||
data = smallput_data,
|
|
||||||
wmask = Some(smallput_wmask))(outerConfig)
|
|
||||||
|
|
||||||
val sending_put = Reg(init = Bool(false))
|
|
||||||
|
|
||||||
val pass_valid = io.in.acquire.valid && !stretch
|
|
||||||
|
|
||||||
io.out.acquire.bits := MuxBundle(Wire(io.out.acquire.bits, init=iacq), Seq(
|
|
||||||
(sending_put, put_block_acquire),
|
|
||||||
(shrink, get_block_acquire),
|
|
||||||
(smallput, put_acquire),
|
|
||||||
(smallget, get_acquire)))
|
|
||||||
io.out.acquire.valid := sending_put || pass_valid
|
|
||||||
io.in.acquire.ready := !sending_put && (stretch || io.out.acquire.ready)
|
|
||||||
|
|
||||||
when (io.in.acquire.fire() && stretch) {
|
|
||||||
acq_data_buffer := iacq.data
|
|
||||||
acq_wmask_buffer := iacq.wmask()
|
|
||||||
acq_client_id := iacq.client_xact_id
|
|
||||||
acq_addr_block := iacq.addr_block
|
|
||||||
acq_addr_beat := iacq.addr_beat
|
|
||||||
sending_put := Bool(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
when (sending_put && io.out.acquire.ready) {
|
|
||||||
acq_data_buffer := acq_data_buffer >> outerDataBits
|
|
||||||
acq_wmask_buffer := acq_wmask_buffer >> outerWriteMaskBits
|
|
||||||
when (oacq_ctr.inc()) { sending_put := Bool(false) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val ognt_block = ognt.hasMultibeatData()
|
|
||||||
val gnt_data_buffer = Reg(Vec(factor, UInt(width = outerDataBits)))
|
|
||||||
val gnt_client_id = Reg(ognt.client_xact_id)
|
|
||||||
val gnt_manager_id = Reg(ognt.manager_xact_id)
|
|
||||||
|
|
||||||
val ignt_ctr = Counter(innerDataBeats)
|
|
||||||
val ognt_ctr = Counter(factor)
|
|
||||||
val sending_get = Reg(init = Bool(false))
|
|
||||||
|
|
||||||
val get_block_grant = Grant(
|
|
||||||
is_builtin_type = Bool(true),
|
|
||||||
g_type = Grant.getDataBlockType,
|
|
||||||
client_xact_id = gnt_client_id,
|
|
||||||
manager_xact_id = gnt_manager_id,
|
|
||||||
addr_beat = ignt_ctr.value,
|
|
||||||
data = gnt_data_buffer.toBits)(innerConfig)
|
|
||||||
|
|
||||||
val smallget_grant = ognt.g_type === Grant.getDataBeatType
|
|
||||||
|
|
||||||
val get_grant = Grant(
|
|
||||||
is_builtin_type = Bool(true),
|
|
||||||
g_type = Grant.getDataBeatType,
|
|
||||||
client_xact_id = ognt.client_xact_id,
|
|
||||||
manager_xact_id = ognt.manager_xact_id,
|
|
||||||
addr_beat = ognt.addr_beat >> UInt(log2Up(factor)),
|
|
||||||
data = Fill(factor, ognt.data))(innerConfig)
|
|
||||||
|
|
||||||
io.in.grant.valid := sending_get || (io.out.grant.valid && !ognt_block)
|
|
||||||
io.out.grant.ready := !sending_get && (ognt_block || io.in.grant.ready)
|
|
||||||
|
|
||||||
io.in.grant.bits := MuxBundle(Wire(io.in.grant.bits, init=ognt), Seq(
|
|
||||||
sending_get -> get_block_grant,
|
|
||||||
smallget_grant -> get_grant))
|
|
||||||
|
|
||||||
when (io.out.grant.valid && ognt_block && !sending_get) {
|
|
||||||
gnt_data_buffer(ognt_ctr.value) := ognt.data
|
|
||||||
when (ognt_ctr.inc()) {
|
|
||||||
gnt_client_id := ognt.client_xact_id
|
|
||||||
gnt_manager_id := ognt.manager_xact_id
|
|
||||||
sending_get := Bool(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when (io.in.grant.ready && sending_get) {
|
|
||||||
ignt_ctr.inc()
|
|
||||||
sending_get := Bool(false)
|
|
||||||
}
|
|
||||||
} else { io.out <> io.in }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MMIOTileLinkManagerData(implicit p: Parameters)
|
class MMIOTileLinkManagerData(implicit p: Parameters)
|
||||||
|
Loading…
Reference in New Issue
Block a user