1
0

make sure TL -> NASTI converter acquire ready not dependent on valid

This commit is contained in:
Howard Mao 2015-10-19 22:46:03 -07:00
parent 1c135c1628
commit ffe7df2fed

View File

@ -1421,33 +1421,43 @@ class NastiIOTileLinkIOConverter(implicit p: Parameters) extends TLModule()(p)
require(tlDataBeats < (1 << nastiXLenBits), "Can't have that many beats") require(tlDataBeats < (1 << nastiXLenBits), "Can't have that many beats")
require(dstIdBits + tlClientXactIdBits < nastiXIdBits, "NastiIO converter is going truncate tags: " + dstIdBits + " + " + tlClientXactIdBits + " >= " + nastiXIdBits) require(dstIdBits + tlClientXactIdBits < nastiXIdBits, "NastiIO converter is going truncate tags: " + dstIdBits + " + " + tlClientXactIdBits + " >= " + nastiXIdBits)
io.tl.acquire.ready := Bool(false)
io.nasti.b.ready := Bool(false)
io.nasti.r.ready := Bool(false)
io.nasti.ar.valid := Bool(false)
io.nasti.aw.valid := Bool(false)
io.nasti.w.valid := Bool(false)
val dst_off = dstIdBits + tlClientXactIdBits val dst_off = dstIdBits + tlClientXactIdBits
val has_data = io.tl.acquire.bits.hasData() val has_data = io.tl.acquire.bits.hasData()
val is_write = io.tl.acquire.valid && has_data
val is_subblock = io.tl.acquire.bits.isSubBlockType() val is_subblock = io.tl.acquire.bits.isSubBlockType()
val is_multibeat = io.tl.acquire.bits.hasMultibeatData() val is_multibeat = io.tl.acquire.bits.hasMultibeatData()
val (tl_cnt_out, tl_wrap_out) = Counter( val (tl_cnt_out, tl_wrap_out) = Counter(
io.tl.acquire.fire() && is_multibeat, tlDataBeats) io.tl.acquire.fire() && is_multibeat, tlDataBeats)
val get_valid = io.tl.acquire.valid && !has_data
val put_valid = io.tl.acquire.valid && has_data
// Reorder queue saves extra information needed to send correct // Reorder queue saves extra information needed to send correct
// grant back to TL client // grant back to TL client
val roq = Module(new ReorderQueue( val roq = Module(new ReorderQueue(
new NastiIOTileLinkIOConverterInfo, new NastiIOTileLinkIOConverterInfo,
nastiRIdBits, tlMaxClientsPerPort)) nastiRIdBits, tlMaxClientsPerPort))
// For Get/GetBlock, make sure Reorder queue can accept new entry
val get_helper = DecoupledHelper(
get_valid,
roq.io.enq.ready,
io.nasti.ar.ready)
val w_inflight = Reg(init = Bool(false))
// For Put/PutBlock, make sure aw and w channel are both ready before
// we send the first beat
val aw_ready = w_inflight || io.nasti.aw.ready
val put_helper = DecoupledHelper(
put_valid,
aw_ready,
io.nasti.w.ready)
val (nasti_cnt_out, nasti_wrap_out) = Counter( val (nasti_cnt_out, nasti_wrap_out) = Counter(
io.nasti.r.fire() && !roq.io.deq.data.subblock, tlDataBeats) io.nasti.r.fire() && !roq.io.deq.data.subblock, tlDataBeats)
roq.io.enq.valid := io.tl.acquire.fire() && !has_data roq.io.enq.valid := get_helper.fire(roq.io.enq.ready)
roq.io.enq.bits.tag := io.nasti.ar.bits.id roq.io.enq.bits.tag := io.nasti.ar.bits.id
roq.io.enq.bits.data.byteOff := io.tl.acquire.bits.addr_byte() roq.io.enq.bits.data.byteOff := io.tl.acquire.bits.addr_byte()
roq.io.enq.bits.data.subblock := is_subblock roq.io.enq.bits.data.subblock := is_subblock
@ -1455,46 +1465,37 @@ 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
// 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.bits := NastiReadAddressChannel( io.nasti.ar.bits := NastiReadAddressChannel(
id = io.tl.acquire.bits.client_xact_id, id = io.tl.acquire.bits.client_xact_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()),
UInt(log2Ceil(tlDataBytes))), UInt(log2Ceil(tlDataBytes))),
len = Mux(is_subblock, UInt(0), UInt(tlDataBeats - 1))) len = Mux(is_subblock, UInt(0), UInt(tlDataBeats - 1)))
io.nasti.aw.valid := put_helper.fire(aw_ready, !w_inflight)
io.nasti.aw.bits := NastiWriteAddressChannel( io.nasti.aw.bits := NastiWriteAddressChannel(
id = io.tl.acquire.bits.client_xact_id, id = io.tl.acquire.bits.client_xact_id,
addr = io.tl.acquire.bits.full_addr(), addr = io.tl.acquire.bits.full_addr(),
size = UInt(log2Ceil(tlDataBytes)), size = UInt(log2Ceil(tlDataBytes)),
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.bits := NastiWriteDataChannel( io.nasti.w.bits := NastiWriteDataChannel(
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))
val w_inflight = Reg(init = Bool(false)) io.tl.acquire.ready := Mux(has_data,
put_helper.fire(put_valid),
get_helper.fire(get_valid))
when (!w_inflight && io.tl.acquire.valid) { when (!w_inflight && io.tl.acquire.fire() && is_multibeat) {
when (has_data) { w_inflight := Bool(true)
// For Put/PutBlock, make sure aw and w channel are both ready before
// we send the first beat
io.tl.acquire.ready := io.nasti.aw.ready && io.nasti.w.ready
io.nasti.aw.valid := io.nasti.w.ready
io.nasti.w.valid := io.nasti.aw.ready
// For Putblock, use a different state for the subsequent beats
when (io.tl.acquire.ready && is_multibeat) { w_inflight := Bool(true) }
} .otherwise {
// For Get/GetBlock, make sure Reorder queue can accept new entry
io.tl.acquire.ready := io.nasti.ar.ready && roq.io.enq.ready
io.nasti.ar.valid := roq.io.enq.ready
}
} }
when (w_inflight) { when (w_inflight) {
io.nasti.w.valid := io.tl.acquire.valid
io.tl.acquire.ready := io.nasti.w.ready
when (tl_wrap_out) { w_inflight := Bool(false) } when (tl_wrap_out) { w_inflight := Bool(false) }
} }