tilelink2: allow preemption of Fragmenter and WidthWidget
This commit is contained in:
parent
b42cfdc9dd
commit
99c7003d11
@ -191,7 +191,8 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten
|
|||||||
val maxLgHints = maxHints .map(m => if (m == 0) lgMinSize else UInt(log2Ceil(m)))
|
val maxLgHints = maxHints .map(m => if (m == 0) lgMinSize else UInt(log2Ceil(m)))
|
||||||
|
|
||||||
// Make the request Irrevocable
|
// Make the request Irrevocable
|
||||||
val in_a = Queue(in.a, 1, flow=true)
|
val repeat = Wire(Bool())
|
||||||
|
val in_a = Repeater(in.a, repeat)
|
||||||
|
|
||||||
// If this is infront of a single manager, these become constants
|
// If this is infront of a single manager, these become constants
|
||||||
val find = manager.findFast(edgeIn.address(in_a.bits))
|
val find = manager.findFast(edgeIn.address(in_a.bits))
|
||||||
@ -226,10 +227,8 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten
|
|||||||
|
|
||||||
when (out.a.fire()) { gennum := new_gennum }
|
when (out.a.fire()) { gennum := new_gennum }
|
||||||
|
|
||||||
val delay = !aHasData && aFragnum =/= UInt(0)
|
repeat := !aHasData && aFragnum =/= UInt(0)
|
||||||
out.a.valid := in_a.valid
|
out.a <> in_a
|
||||||
in_a.ready := out.a.ready && !delay
|
|
||||||
out.a.bits := in_a.bits
|
|
||||||
out.a.bits.addr_hi := in_a.bits.addr_hi | (~aFragnum << log2Ceil(minSize/beatBytes) & aOrigOH1 >> log2Ceil(beatBytes))
|
out.a.bits.addr_hi := in_a.bits.addr_hi | (~aFragnum << log2Ceil(minSize/beatBytes) & aOrigOH1 >> log2Ceil(beatBytes))
|
||||||
out.a.bits.source := Cat(in_a.bits.source, aFragnum)
|
out.a.bits.source := Cat(in_a.bits.source, aFragnum)
|
||||||
out.a.bits.size := aFrag
|
out.a.bits.size := aFrag
|
||||||
|
37
src/main/scala/uncore/tilelink2/Repeater.scala
Normal file
37
src/main/scala/uncore/tilelink2/Repeater.scala
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
package uncore.tilelink2
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
|
||||||
|
// A Repeater passes it's input to it's output, unless repeat is asserted.
|
||||||
|
// When repeat is asserted, the Repeater copies the input and repeats it next cycle.
|
||||||
|
class Repeater[T <: Data](gen: T) extends Module
|
||||||
|
{
|
||||||
|
val io = new Bundle {
|
||||||
|
val repeat = Bool(INPUT)
|
||||||
|
val enq = Decoupled(gen).flip
|
||||||
|
val deq = Decoupled(gen)
|
||||||
|
}
|
||||||
|
|
||||||
|
val full = RegInit(Bool(false))
|
||||||
|
val saved = Reg(gen)
|
||||||
|
|
||||||
|
// When !full, a repeater is pass-through
|
||||||
|
io.deq.valid := io.enq.valid || full
|
||||||
|
io.enq.ready := io.deq.ready && !full
|
||||||
|
io.deq.bits := Mux(full, saved, io.enq.bits)
|
||||||
|
|
||||||
|
when (io.enq.fire() && io.repeat) { full := Bool(true); saved := io.enq.bits }
|
||||||
|
when (io.deq.fire() && !io.repeat) { full := Bool(false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
object Repeater
|
||||||
|
{
|
||||||
|
def apply[T <: Data](enq: DecoupledIO[T], repeat: Bool): DecoupledIO[T] = {
|
||||||
|
val repeater = Module(new Repeater(enq.bits))
|
||||||
|
repeater.io.repeat := repeat
|
||||||
|
repeater.io.enq := enq
|
||||||
|
repeater.io.deq
|
||||||
|
}
|
||||||
|
}
|
@ -120,9 +120,7 @@ class TLWidthWidget(innerBeatBytes: Int) extends LazyModule
|
|||||||
val dataOut = if (edgeIn.staticHasData(in.bits) == Some(false)) UInt(0) else Mux1H(select, dataSlices)
|
val dataOut = if (edgeIn.staticHasData(in.bits) == Some(false)) UInt(0) else Mux1H(select, dataSlices)
|
||||||
val maskOut = Mux1H(select, maskSlices)
|
val maskOut = Mux1H(select, maskSlices)
|
||||||
|
|
||||||
in.ready := out.ready && last
|
out <> in
|
||||||
out.valid := in.valid
|
|
||||||
out.bits := in.bits
|
|
||||||
edgeOut.data(out.bits) := dataOut
|
edgeOut.data(out.bits) := dataOut
|
||||||
|
|
||||||
out.bits match {
|
out.bits match {
|
||||||
@ -133,6 +131,9 @@ class TLWidthWidget(innerBeatBytes: Int) extends LazyModule
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addr_lo gets truncated automagically
|
// addr_lo gets truncated automagically
|
||||||
|
|
||||||
|
// Repeat the input if we're not last
|
||||||
|
!last
|
||||||
}
|
}
|
||||||
|
|
||||||
def splice[T <: TLDataChannel](edgeIn: TLEdge, in: DecoupledIO[T], edgeOut: TLEdge, out: DecoupledIO[T]) = {
|
def splice[T <: TLDataChannel](edgeIn: TLEdge, in: DecoupledIO[T], edgeOut: TLEdge, out: DecoupledIO[T]) = {
|
||||||
@ -141,7 +142,8 @@ class TLWidthWidget(innerBeatBytes: Int) extends LazyModule
|
|||||||
out <> in
|
out <> in
|
||||||
} else if (edgeIn.manager.beatBytes > edgeOut.manager.beatBytes) {
|
} else if (edgeIn.manager.beatBytes > edgeOut.manager.beatBytes) {
|
||||||
// split input to output
|
// split input to output
|
||||||
split(edgeIn, Queue(in, 1, flow=true), edgeOut, out)
|
val repeat = Wire(Bool())
|
||||||
|
repeat := split(edgeIn, Repeater(in, repeat), edgeOut, out)
|
||||||
} else {
|
} else {
|
||||||
// merge input to output
|
// merge input to output
|
||||||
merge(edgeIn, in, edgeOut, out)
|
merge(edgeIn, in, edgeOut, out)
|
||||||
|
Loading…
Reference in New Issue
Block a user