using pingpong buffer
This commit is contained in:
@@ -33,7 +33,7 @@ abstract class DMAMstBase(val edgeOut: TLEdgeOut)(implicit p: Parameters) extend
|
|||||||
|
|
||||||
val rxBuff = Module(new RxBuff(8))
|
val rxBuff = Module(new RxBuff(8))
|
||||||
val txBuff = Module(new TxBuff(0))
|
val txBuff = Module(new TxBuff(0))
|
||||||
rxBuff.io.header.ready := true.B
|
rxBuff.headerIO.ready := true.B
|
||||||
|
|
||||||
|
|
||||||
def stateIdle = 0.U
|
def stateIdle = 0.U
|
||||||
|
|||||||
147
src/main/scala/Switch/PiPoBuff.scala
Normal file
147
src/main/scala/Switch/PiPoBuff.scala
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
package Switch
|
||||||
|
|
||||||
|
import chisel3._
|
||||||
|
import chisel3.util._
|
||||||
|
|
||||||
|
import MAC._
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class PiPoBuffBase[T<:Data]( dp: Int, val threshold: Int = 32) extends Module{
|
||||||
|
|
||||||
|
class PiPoBuffIO extends Bundle{
|
||||||
|
val enq = Flipped(Decoupled(new Mac_Stream_Bundle))
|
||||||
|
val deq = Decoupled(new Mac_Stream_Bundle)
|
||||||
|
}
|
||||||
|
|
||||||
|
val io: PiPoBuffIO = IO(new PiPoBuffIO)
|
||||||
|
|
||||||
|
val isEnqPi = RegInit(true.B)
|
||||||
|
val isEnqPo = ~isEnqPi
|
||||||
|
|
||||||
|
val isDeqPi = RegInit(true.B)
|
||||||
|
val isDeqPo = ~isDeqPi
|
||||||
|
|
||||||
|
|
||||||
|
val buff = for( i <- 0 until 2 ) yield { Module(new Queue( new Mac_Stream_Bundle, dp )) }
|
||||||
|
val isReach = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||||
|
val cnt = RegInit(0.U((log2Ceil(dp)).W))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
buff(0).io.enq.valid := isEnqPi & io.enq.valid
|
||||||
|
buff(0).io.enq.bits := io.enq.bits
|
||||||
|
|
||||||
|
buff(1).io.enq.valid := isEnqPo & io.enq.valid
|
||||||
|
buff(1).io.enq.bits := io.enq.bits
|
||||||
|
|
||||||
|
io.enq.ready :=
|
||||||
|
Mux1H(Seq(
|
||||||
|
isEnqPi -> buff(0).io.enq.ready,
|
||||||
|
isEnqPo -> buff(1).io.enq.ready
|
||||||
|
))
|
||||||
|
|
||||||
|
when( io.enq.fire & io.enq.bits.isLast ){
|
||||||
|
isEnqPi := ~isEnqPi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
when( io.enq.fire ){
|
||||||
|
when( io.enq.bits.isStart ){
|
||||||
|
cnt := 0.U
|
||||||
|
} .otherwise{
|
||||||
|
cnt := cnt + 1.U
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
when( io.enq.fire ){
|
||||||
|
when( io.enq.bits.isStart ){
|
||||||
|
when( isEnqPi ){ isReach(0) := false.B }
|
||||||
|
when( isEnqPo ){ isReach(1) := false.B }
|
||||||
|
} .elsewhen(
|
||||||
|
io.enq.bits.isLast ||
|
||||||
|
(if( threshold != 0 ) { cnt === threshold.U } else {false.B})
|
||||||
|
){
|
||||||
|
when( isEnqPi ){ isReach(0) := true.B }
|
||||||
|
when( isEnqPo ){ isReach(1) := true.B }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
when( io.deq.fire & io.deq.bits.isLast ){
|
||||||
|
isDeqPi := ~isDeqPi
|
||||||
|
}
|
||||||
|
|
||||||
|
io.deq.valid :=
|
||||||
|
Mux1H(Seq(
|
||||||
|
isDeqPi -> ( buff(0).io.deq.valid & isReach(0) ),
|
||||||
|
isDeqPo -> ( buff(1).io.deq.valid & isReach(1) ),
|
||||||
|
))
|
||||||
|
|
||||||
|
io.deq.bits :=
|
||||||
|
Mux1H(Seq(
|
||||||
|
isDeqPi -> buff(0).io.deq.bits,
|
||||||
|
isDeqPo -> buff(1).io.deq.bits,
|
||||||
|
))
|
||||||
|
|
||||||
|
buff(0).io.deq.ready := io.deq.ready & isReach(0) & isDeqPi
|
||||||
|
buff(1).io.deq.ready := io.deq.ready & isReach(1) & isDeqPo
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RxBuff(threshold: Int = 8) extends PiPoBuffBase(2048, threshold){
|
||||||
|
val headerIO = IO(Decoupled(Vec( 20, UInt(8.W) ) ))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
val header = for( i <- 0 until 2 ) yield { Reg(Vec( 20, UInt(8.W) )) }
|
||||||
|
val hValid = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||||
|
|
||||||
|
|
||||||
|
when( io.enq.fire ){
|
||||||
|
when( cnt < 20.U ){
|
||||||
|
when( isEnqPi ){ header(0)(cnt) := io.enq.bits.data }
|
||||||
|
.elsewhen( isEnqPo ){ header(1)(cnt) := io.enq.bits.data
|
||||||
|
} .otherwise{
|
||||||
|
assert(false.B, "Assert Failed, Rx Under Run")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
when( headerIO.fire ){
|
||||||
|
when( isDeqPi ) { hValid(0) := false.B }
|
||||||
|
when( isDeqPo ) { hValid(1) := false.B }
|
||||||
|
} .elsewhen( io.enq.fire & cnt === 20.U ){
|
||||||
|
when( isEnqPi ) { hValid(0) := true.B }
|
||||||
|
when( isEnqPo ) { hValid(1) := true.B }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
headerIO.valid :=
|
||||||
|
Mux1H(Seq(
|
||||||
|
isDeqPi -> hValid(0),
|
||||||
|
isDeqPo -> hValid(1),
|
||||||
|
))
|
||||||
|
|
||||||
|
headerIO.bits :=
|
||||||
|
Mux1H(Seq(
|
||||||
|
isDeqPi -> header(0),
|
||||||
|
isDeqPo -> header(1),
|
||||||
|
))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class TxBuff(threshold: Int = 8) extends PiPoBuffBase(2048, threshold)
|
||||||
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
package Switch
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
|
|
||||||
import MAC._
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RxBuffIO extends Bundle{
|
|
||||||
val enq = Flipped(Decoupled(new Mac_Stream_Bundle))
|
|
||||||
val deq = Decoupled(new Mac_Stream_Bundle)
|
|
||||||
val header = Decoupled(Vec( 20, UInt(8.W) ) )
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RxBuffBase(val threshold: Int = 32) extends Module{
|
|
||||||
val io: RxBuffIO = IO(new RxBuffIO)
|
|
||||||
|
|
||||||
val isEnqPi = RegInit(true.B)
|
|
||||||
val isEnqPo = ~isEnqPi
|
|
||||||
|
|
||||||
val isDeqPi = RegInit(true.B)
|
|
||||||
val isDeqPo = ~isDeqPi
|
|
||||||
|
|
||||||
|
|
||||||
val buff = for( i <- 0 until 2 ) yield { Module(new Queue( new Mac_Stream_Bundle, 2048 )) }
|
|
||||||
|
|
||||||
|
|
||||||
val header = for( i <- 0 until 2 ) yield { Reg(Vec( 20, UInt(8.W) )) }
|
|
||||||
val hValid = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
|
||||||
val isReach = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
|
||||||
|
|
||||||
val recCnt = RegInit(0.U(12.W))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
trait RxBuffEnq{ this: RxBuffBase =>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
buff(0).io.enq.valid := isEnqPi & io.enq.valid
|
|
||||||
buff(0).io.enq.bits := io.enq.bits
|
|
||||||
|
|
||||||
buff(1).io.enq.valid := isEnqPo & io.enq.valid
|
|
||||||
buff(1).io.enq.bits := io.enq.bits
|
|
||||||
|
|
||||||
io.enq.ready := (isEnqPi & buff(0).io.enq.ready) | (isEnqPo & buff(1).io.enq.ready)
|
|
||||||
|
|
||||||
when( io.enq.fire & io.enq.bits.isLast ){
|
|
||||||
isEnqPi := ~isEnqPi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( io.enq.fire ){
|
|
||||||
when( io.enq.bits.isStart ){
|
|
||||||
recCnt := 0.U
|
|
||||||
} .otherwise{
|
|
||||||
recCnt := recCnt + 1.U
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when( io.enq.fire ){
|
|
||||||
when( recCnt < 20.U ){
|
|
||||||
when( isEnqPi ){ header(0)(recCnt) := io.enq.bits.data }
|
|
||||||
.elsewhen( isEnqPo ){ header(1)(recCnt) := io.enq.bits.data
|
|
||||||
} .otherwise{
|
|
||||||
assert(false.B, "Assert Failed, Rx Under Run")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when( io.enq.fire ){
|
|
||||||
when( io.enq.bits.isStart ){
|
|
||||||
when( isEnqPi ){ isReach(0) := false.B }
|
|
||||||
when( isEnqPo ){ isReach(1) := false.B }
|
|
||||||
} .elsewhen(
|
|
||||||
io.enq.bits.isLast ||
|
|
||||||
(if( threshold != 0 ) {recCnt === threshold.U } else {false.B})
|
|
||||||
){
|
|
||||||
when( isEnqPi ){ isReach(0) := true.B }
|
|
||||||
when( isEnqPo ){ isReach(1) := true.B }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait RxBuffDeq{ this: RxBuffBase =>
|
|
||||||
|
|
||||||
when( io.header.fire ){
|
|
||||||
when( isDeqPi ) { hValid(0) := false.B }
|
|
||||||
when( isDeqPo ) { hValid(1) := false.B }
|
|
||||||
} .elsewhen( io.enq.fire & recCnt === 20.U ){
|
|
||||||
when( isEnqPi ) { hValid(0) := true.B }
|
|
||||||
when( isEnqPo ) { hValid(1) := true.B }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when( io.deq.fire & io.deq.bits.isLast ){
|
|
||||||
isDeqPi := ~isDeqPi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
when( isDeqPi ){
|
|
||||||
io.deq.valid := buff(0).io.deq.valid & isReach(0)
|
|
||||||
io.deq.bits := buff(0).io.deq.bits
|
|
||||||
buff(0).io.deq.ready := io.deq.ready & isReach(0)
|
|
||||||
|
|
||||||
buff(1).io.deq.ready := false.B
|
|
||||||
|
|
||||||
io.header.valid := hValid(0)
|
|
||||||
io.header.bits := header(0)
|
|
||||||
} .otherwise{
|
|
||||||
assert( isDeqPo )
|
|
||||||
io.deq.valid := buff(1).io.deq.valid & isReach(1)
|
|
||||||
io.deq.bits := buff(1).io.deq.bits
|
|
||||||
buff(1).io.deq.ready := io.deq.ready & isReach(1)
|
|
||||||
|
|
||||||
buff(0).io.deq.ready := false.B
|
|
||||||
|
|
||||||
io.header.valid := hValid(1)
|
|
||||||
io.header.bits := header(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class RxBuff(threshold: Int = 8) extends RxBuffBase(threshold) with RxBuffEnq with RxBuffDeq{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ class MacNode(implicit p: Parameters) extends Mac{
|
|||||||
val rxBuff = Module(new RxBuff)
|
val rxBuff = Module(new RxBuff)
|
||||||
val txBuff = Module(new TxBuff)
|
val txBuff = Module(new TxBuff)
|
||||||
|
|
||||||
rxBuff.io.header.ready := true.B
|
rxBuff.headerIO.ready := true.B
|
||||||
|
|
||||||
macTileLinkRx.io.rxEnq <> rxBuff.io.enq
|
macTileLinkRx.io.rxEnq <> rxBuff.io.enq
|
||||||
txBuff.io.deq <> macTileLinkTx.io.txDeq
|
txBuff.io.deq <> macTileLinkTx.io.txDeq
|
||||||
|
|||||||
@@ -65,4 +65,4 @@ trait TxBuffDeq{ this: TxBuffBase =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class TxBuff(threshold: Int = 8) extends TxBuffBase(threshold) with TxBuffEnq with TxBuffDeq
|
|
||||||
Reference in New Issue
Block a user