add PutAtomic support to width adapter
This commit is contained in:
parent
47887c40ac
commit
900a7bbcf1
@ -6,6 +6,8 @@ import junctions.PAddrBits
|
|||||||
import uncore.tilelink._
|
import uncore.tilelink._
|
||||||
import uncore.util._
|
import uncore.util._
|
||||||
import uncore.constants._
|
import uncore.constants._
|
||||||
|
import uncore.devices.TileLinkTestRAM
|
||||||
|
import unittest.UnitTest
|
||||||
import cde.Parameters
|
import cde.Parameters
|
||||||
|
|
||||||
/** Utilities for safely wrapping a *UncachedTileLink by pinning probe.ready and release.valid low */
|
/** Utilities for safely wrapping a *UncachedTileLink by pinning probe.ready and release.valid low */
|
||||||
@ -222,6 +224,8 @@ class TileLinkIOWidener(innerTLId: String, outerTLId: String)
|
|||||||
val stretch = ognt.g_type === Grant.getDataBlockType
|
val stretch = ognt.g_type === Grant.getDataBlockType
|
||||||
val smallget = iacq.a_type === Acquire.getType
|
val smallget = iacq.a_type === Acquire.getType
|
||||||
val smallput = iacq.a_type === Acquire.putType
|
val smallput = iacq.a_type === Acquire.putType
|
||||||
|
val atomic = iacq.a_type === Acquire.putAtomicType
|
||||||
|
val wideget = iacq.a_type === Acquire.getBlockType
|
||||||
val smallgnt = ognt.g_type === Grant.getDataBeatType
|
val smallgnt = ognt.g_type === Grant.getDataBeatType
|
||||||
|
|
||||||
val sending_put = Reg(init = Bool(false))
|
val sending_put = Reg(init = Bool(false))
|
||||||
@ -278,13 +282,32 @@ class TileLinkIOWidener(innerTLId: String, outerTLId: String)
|
|||||||
data = put_data.asUInt,
|
data = put_data.asUInt,
|
||||||
wmask = Some(put_wmask.asUInt))(outerConfig)
|
wmask = Some(put_wmask.asUInt))(outerConfig)
|
||||||
|
|
||||||
|
val put_atomic_acquire = PutAtomic(
|
||||||
|
client_xact_id = iacq.client_xact_id,
|
||||||
|
addr_block = out_addr_block,
|
||||||
|
addr_beat = out_addr_beat,
|
||||||
|
addr_byte = out_addr_byte,
|
||||||
|
atomic_opcode = iacq.op_code(),
|
||||||
|
operand_size = iacq.op_size(),
|
||||||
|
data = align_data(switch_addr, iacq.data))(outerConfig)
|
||||||
|
|
||||||
|
val default_acquire = Acquire(
|
||||||
|
is_builtin_type = Bool(true),
|
||||||
|
a_type = iacq.a_type,
|
||||||
|
client_xact_id = iacq.client_xact_id,
|
||||||
|
addr_block = iacq.addr_block)(outerConfig)
|
||||||
|
|
||||||
io.out.acquire.valid := sending_put || (!shrink && io.in.acquire.valid)
|
io.out.acquire.valid := sending_put || (!shrink && io.in.acquire.valid)
|
||||||
io.out.acquire.bits := MuxCase(get_block_acquire, Seq(
|
io.out.acquire.bits := MuxCase(default_acquire, Seq(
|
||||||
sending_put -> put_block_acquire,
|
sending_put -> put_block_acquire,
|
||||||
|
wideget -> get_block_acquire,
|
||||||
smallget -> get_acquire,
|
smallget -> get_acquire,
|
||||||
smallput -> put_acquire))
|
smallput -> put_acquire,
|
||||||
|
atomic -> put_atomic_acquire))
|
||||||
io.in.acquire.ready := !sending_put && (shrink || io.out.acquire.ready)
|
io.in.acquire.ready := !sending_put && (shrink || io.out.acquire.ready)
|
||||||
|
|
||||||
|
assert(!io.in.acquire.valid || iacq.isBuiltInType(), "Non-builtin acquires not supported by widener")
|
||||||
|
|
||||||
when (io.in.acquire.fire() && shrink) {
|
when (io.in.acquire.fire() && shrink) {
|
||||||
when (!collecting) {
|
when (!collecting) {
|
||||||
put_block := out_addr_block
|
put_block := out_addr_block
|
||||||
@ -351,8 +374,8 @@ class TileLinkIOWidener(innerTLId: String, outerTLId: String)
|
|||||||
g_type = ognt.g_type,
|
g_type = ognt.g_type,
|
||||||
client_xact_id = ognt.client_xact_id,
|
client_xact_id = ognt.client_xact_id,
|
||||||
manager_xact_id = ognt.manager_xact_id,
|
manager_xact_id = ognt.manager_xact_id,
|
||||||
addr_beat = ognt.addr_beat,
|
addr_beat = UInt(0),
|
||||||
data = ognt.data)(innerConfig)
|
data = UInt(0))(innerConfig)
|
||||||
|
|
||||||
io.in.grant.valid := returning_data || (!stretch && io.out.grant.valid)
|
io.in.grant.valid := returning_data || (!stretch && io.out.grant.valid)
|
||||||
io.in.grant.bits := MuxCase(default_grant, Seq(
|
io.in.grant.bits := MuxCase(default_grant, Seq(
|
||||||
@ -395,9 +418,10 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
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 wideget = 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 atomic = iacq.a_type === Acquire.putAtomicType
|
||||||
|
|
||||||
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))
|
||||||
@ -434,6 +458,9 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
assert(!io.in.acquire.valid || !smallget || read_size_ok,
|
assert(!io.in.acquire.valid || !smallget || read_size_ok,
|
||||||
"Can't perform Get wider than outer width")
|
"Can't perform Get wider than outer width")
|
||||||
|
|
||||||
|
assert(!io.in.acquire.valid || !atomic || read_size_ok,
|
||||||
|
"Can't perform PutAtomic wider than outer width")
|
||||||
|
|
||||||
val outerConfig = p.alterPartial({ case TLId => outerTLId })
|
val outerConfig = p.alterPartial({ case TLId => outerTLId })
|
||||||
val innerConfig = p.alterPartial({ case TLId => innerTLId })
|
val innerConfig = p.alterPartial({ case TLId => innerTLId })
|
||||||
|
|
||||||
@ -466,18 +493,43 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
data = smallput_data,
|
data = smallput_data,
|
||||||
wmask = Some(smallput_wmask))(outerConfig)
|
wmask = Some(smallput_wmask))(outerConfig)
|
||||||
|
|
||||||
val sending_put = Reg(init = Bool(false))
|
val atomic_addr = iacq.full_addr()
|
||||||
|
val atomic_addr_beat = atomic_addr(outerBlockOffset - 1, outerByteAddrBits)
|
||||||
|
val atomic_addr_byte = atomic_addr(outerByteAddrBits - 1, 0)
|
||||||
|
val atomic_data_sel = atomic_addr(outerByteAddrBits + log2Up(factor) - 1, outerByteAddrBits)
|
||||||
|
val atomic_data_vec = Vec(Seq.tabulate(factor) {
|
||||||
|
i => iacq.data((i + 1) * outerDataBits - 1, i * outerDataBits)
|
||||||
|
})
|
||||||
|
|
||||||
|
val put_atomic_acquire = PutAtomic(
|
||||||
|
client_xact_id = iacq.client_xact_id,
|
||||||
|
addr_block = iacq.addr_block,
|
||||||
|
addr_beat = atomic_addr_beat,
|
||||||
|
addr_byte = atomic_addr_byte,
|
||||||
|
atomic_opcode = iacq.op_code(),
|
||||||
|
operand_size = iacq.op_size(),
|
||||||
|
data = atomic_data_vec(atomic_data_sel))(outerConfig)
|
||||||
|
|
||||||
|
val default_acquire = Acquire(
|
||||||
|
is_builtin_type = Bool(true),
|
||||||
|
a_type = iacq.a_type,
|
||||||
|
client_xact_id = iacq.client_xact_id,
|
||||||
|
addr_block = iacq.addr_block)(outerConfig)
|
||||||
|
|
||||||
|
val sending_put = Reg(init = Bool(false))
|
||||||
val pass_valid = io.in.acquire.valid && !stretch
|
val pass_valid = io.in.acquire.valid && !stretch
|
||||||
|
|
||||||
io.out.acquire.bits := MuxCase(Wire(io.out.acquire.bits, init=iacq), Seq(
|
io.out.acquire.bits := MuxCase(default_acquire, Seq(
|
||||||
(sending_put, put_block_acquire),
|
sending_put -> put_block_acquire,
|
||||||
(shrink, get_block_acquire),
|
wideget -> get_block_acquire,
|
||||||
(smallput, put_acquire),
|
smallput -> put_acquire,
|
||||||
(smallget, get_acquire)))
|
smallget -> get_acquire,
|
||||||
|
atomic -> put_atomic_acquire))
|
||||||
io.out.acquire.valid := sending_put || pass_valid
|
io.out.acquire.valid := sending_put || pass_valid
|
||||||
io.in.acquire.ready := !sending_put && (stretch || io.out.acquire.ready)
|
io.in.acquire.ready := !sending_put && (stretch || io.out.acquire.ready)
|
||||||
|
|
||||||
|
assert(!io.in.acquire.valid || iacq.isBuiltInType(), "Non-builtin acquires not supported by narrower")
|
||||||
|
|
||||||
when (io.in.acquire.fire() && stretch) {
|
when (io.in.acquire.fire() && stretch) {
|
||||||
acq_data_buffer := iacq.data
|
acq_data_buffer := iacq.data
|
||||||
acq_wmask_buffer := iacq.wmask()
|
acq_wmask_buffer := iacq.wmask()
|
||||||
@ -493,7 +545,6 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
when (oacq_ctr.inc()) { sending_put := Bool(false) }
|
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_data_buffer = Reg(Vec(factor, UInt(width = outerDataBits)))
|
||||||
val gnt_client_id = Reg(ognt.client_xact_id)
|
val gnt_client_id = Reg(ognt.client_xact_id)
|
||||||
val gnt_manager_id = Reg(ognt.manager_xact_id)
|
val gnt_manager_id = Reg(ognt.manager_xact_id)
|
||||||
@ -502,6 +553,9 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
val ognt_ctr = Counter(factor)
|
val ognt_ctr = Counter(factor)
|
||||||
val sending_get = Reg(init = Bool(false))
|
val sending_get = Reg(init = Bool(false))
|
||||||
|
|
||||||
|
val smallget_grant = ognt.g_type === Grant.getDataBeatType
|
||||||
|
val wideget_grant = ognt.hasMultibeatData()
|
||||||
|
|
||||||
val get_block_grant = Grant(
|
val get_block_grant = Grant(
|
||||||
is_builtin_type = Bool(true),
|
is_builtin_type = Bool(true),
|
||||||
g_type = Grant.getDataBlockType,
|
g_type = Grant.getDataBlockType,
|
||||||
@ -510,8 +564,6 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
addr_beat = ignt_ctr.value,
|
addr_beat = ignt_ctr.value,
|
||||||
data = gnt_data_buffer.asUInt)(innerConfig)
|
data = gnt_data_buffer.asUInt)(innerConfig)
|
||||||
|
|
||||||
val smallget_grant = ognt.g_type === Grant.getDataBeatType
|
|
||||||
|
|
||||||
val get_grant = Grant(
|
val get_grant = Grant(
|
||||||
is_builtin_type = Bool(true),
|
is_builtin_type = Bool(true),
|
||||||
g_type = Grant.getDataBeatType,
|
g_type = Grant.getDataBeatType,
|
||||||
@ -520,14 +572,22 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
addr_beat = ognt.addr_beat >> UInt(log2Up(factor)),
|
addr_beat = ognt.addr_beat >> UInt(log2Up(factor)),
|
||||||
data = Fill(factor, ognt.data))(innerConfig)
|
data = Fill(factor, ognt.data))(innerConfig)
|
||||||
|
|
||||||
io.in.grant.valid := sending_get || (io.out.grant.valid && !ognt_block)
|
val default_grant = Grant(
|
||||||
io.out.grant.ready := !sending_get && (ognt_block || io.in.grant.ready)
|
is_builtin_type = Bool(true),
|
||||||
|
g_type = ognt.g_type,
|
||||||
|
client_xact_id = ognt.client_xact_id,
|
||||||
|
manager_xact_id = ognt.manager_xact_id,
|
||||||
|
addr_beat = UInt(0),
|
||||||
|
data = UInt(0))(innerConfig)
|
||||||
|
|
||||||
io.in.grant.bits := MuxCase(Wire(io.in.grant.bits, init=ognt), Seq(
|
io.in.grant.valid := sending_get || (io.out.grant.valid && !wideget_grant)
|
||||||
|
io.out.grant.ready := !sending_get && (wideget_grant || io.in.grant.ready)
|
||||||
|
|
||||||
|
io.in.grant.bits := MuxCase(default_grant, Seq(
|
||||||
sending_get -> get_block_grant,
|
sending_get -> get_block_grant,
|
||||||
smallget_grant -> get_grant))
|
smallget_grant -> get_grant))
|
||||||
|
|
||||||
when (io.out.grant.valid && ognt_block && !sending_get) {
|
when (io.out.grant.valid && wideget_grant && !sending_get) {
|
||||||
gnt_data_buffer(ognt_ctr.value) := ognt.data
|
gnt_data_buffer(ognt_ctr.value) := ognt.data
|
||||||
when (ognt_ctr.inc()) {
|
when (ognt_ctr.inc()) {
|
||||||
gnt_client_id := ognt.client_xact_id
|
gnt_client_id := ognt.client_xact_id
|
||||||
@ -542,6 +602,35 @@ class TileLinkIONarrower(innerTLId: String, outerTLId: String)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TileLinkWidthAdapterTest(implicit p: Parameters) extends UnitTest {
|
||||||
|
val narrowConfig = p(TLKey(p(TLId)))
|
||||||
|
val wideConfig = narrowConfig.copy(
|
||||||
|
dataBeats = narrowConfig.dataBeats / 2)
|
||||||
|
val adapterParams = p.alterPartial({ case TLKey("WIDE") => wideConfig })
|
||||||
|
|
||||||
|
val depth = 2 * narrowConfig.dataBeats
|
||||||
|
val ram = Module(new TileLinkTestRAM(depth))
|
||||||
|
val driver = Module(new DriverSet(
|
||||||
|
(driverParams: Parameters) => {
|
||||||
|
implicit val p = driverParams
|
||||||
|
Seq(
|
||||||
|
Module(new PutSweepDriver(depth)),
|
||||||
|
Module(new PutMaskDriver),
|
||||||
|
Module(new PutAtomicDriver),
|
||||||
|
Module(new PutBlockSweepDriver(depth / narrowConfig.dataBeats)),
|
||||||
|
Module(new PrefetchDriver),
|
||||||
|
Module(new GetMultiWidthDriver))
|
||||||
|
}))
|
||||||
|
val widener = Module(new TileLinkIOWidener(p(TLId), "WIDE")(adapterParams))
|
||||||
|
val narrower = Module(new TileLinkIONarrower("WIDE", p(TLId))(adapterParams))
|
||||||
|
|
||||||
|
widener.io.in <> driver.io.mem
|
||||||
|
narrower.io.in <> widener.io.out
|
||||||
|
ram.io <> narrower.io.out
|
||||||
|
driver.io.start := io.start
|
||||||
|
io.finished := driver.io.finished
|
||||||
|
}
|
||||||
|
|
||||||
class TileLinkFragmenterSource(implicit p: Parameters) extends TLModule()(p) {
|
class TileLinkFragmenterSource(implicit p: Parameters) extends TLModule()(p) {
|
||||||
val io = new Bundle {
|
val io = new Bundle {
|
||||||
val in = Decoupled(new Acquire).flip
|
val in = Decoupled(new Acquire).flip
|
||||||
|
@ -25,6 +25,7 @@ class WithUncoreUnitTests extends Config(
|
|||||||
case UnitTests => (p: Parameters) => Seq(
|
case UnitTests => (p: Parameters) => Seq(
|
||||||
Module(new uncore.devices.ROMSlaveTest()(p)),
|
Module(new uncore.devices.ROMSlaveTest()(p)),
|
||||||
Module(new uncore.devices.TileLinkRAMTest()(p)),
|
Module(new uncore.devices.TileLinkRAMTest()(p)),
|
||||||
|
Module(new uncore.converters.TileLinkWidthAdapterTest()(p)),
|
||||||
Module(new uncore.tilelink2.TLFuzzRAMTest),
|
Module(new uncore.tilelink2.TLFuzzRAMTest),
|
||||||
Module(new uncore.axi4.AXI4LiteFuzzRAMTest),
|
Module(new uncore.axi4.AXI4LiteFuzzRAMTest),
|
||||||
Module(new uncore.axi4.AXI4FullFuzzRAMTest),
|
Module(new uncore.axi4.AXI4FullFuzzRAMTest),
|
||||||
|
Loading…
Reference in New Issue
Block a user