Files
eb001/src/main/scala/backBoard/ebus/TL2CDR.scala

421 lines
15 KiB
Scala
Raw Normal View History

2025-01-09 19:10:07 +08:00
package BACK
import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
abstract class BackModule(implicit val p: Parameters) extends Module with HasBackParameters { def io: Record }
abstract class BackBundle(implicit val p: Parameters) extends Bundle with HasBackParameters
case object BackParamsKey extends Field[BackSetting]
case class BackSetting(
){
}
trait HasBackParameters {
implicit val p: Parameters
val backSetting = p(BackParamsKey)
}
class BackCfg extends Config((_, _, _) => {
case BackParamsKey => BackSetting()
})
abstract class TL2CDRBase(val edge: TLEdgeIn)(implicit p: Parameters) extends BackModule {
class TLCDRIO extends Bundle{
val overCLK = Input(Bool())
val dDatIn = Input(Bool())
val dDatOut = Output(Bool())
val uDatIn = Input(Bool())
val uDatOut = Output(Bool())
val tla = Flipped(new DecoupledIO(new TLBundleA(edge.bundle)))
val tld = new DecoupledIO(new TLBundleD(edge.bundle))
2025-02-05 18:06:52 +08:00
val interrupt = Output(Vec(8, Bool()))
2025-01-16 17:57:44 +08:00
val isOnline = Output(Bool())
val isLast = Input(Bool())
2025-01-09 19:10:07 +08:00
}
val io: TLCDRIO = IO(new TLCDRIO)
2025-02-05 18:06:52 +08:00
val CDRIn = for( i <- 0 until 2 ) yield { Module(new CDRIn) }
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
CDRIn(0).io.serDat := io.dDatIn
CDRIn(1).io.serDat := io.uDatIn
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
CDRIn(0).io.overCLK := io.overCLK
CDRIn(1).io.overCLK := io.overCLK
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
val CDROut = for( i <- 0 until 2 ) yield { Module(new CDROut) }
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
io.dDatOut := CDROut(0).io.serDat
io.uDatOut := CDROut(1).io.serDat
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
val txFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
val rxFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
val isTLWriteSoftReset = for( i <- 0 until 4 ) yield { Wire(Bool()) } //io.tla.fire & io.tla.bits.address(5,0) === "h10".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
val isTLReadStatus = Wire( Bool() ) //io.tla.fire & io.tla.bits.address(5,0) === "h0".U & ( io.tla.bits.opcode === 4.U )
2025-01-09 19:10:07 +08:00
}
trait TL2CDRTx{ this: TL2CDRBase =>
2025-02-05 18:06:52 +08:00
val isTLWriteTxLen = for( i <- 0 until 2 ) yield { Wire( Bool()) }//io.tla.fire & io.tla.bits.address(5,0) === "h4".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
val isTLWriteTxFifo = for( i <- 0 until 2 ) yield { Wire( Bool()) }//io.tla.fire & io.tla.bits.address(5,0) === "h8".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
val isTxFifoRelease = for( i <- 0 until 2 ) yield { Wire( Bool()) }
val txLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
val isTxBusy = for( i <- 0 until 2 ) yield { RegInit(false.B) }
val isTxFull = for( i <- 0 until 2 ) yield { ~txFifo(i).io.enq.ready }
val intTxFifoFull = for( i <- 0 until 2 ) yield { ~RegNext(isTxFull(i), false.B) & isTxFull(i) }
val intTxFinish = for( i <- 0 until 2 ) yield { CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast }
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
// val intTxEnd = ShiftRegister( CDROut.io.axis.fire & CDROut.io.axis.bits.tlast, 5, false.B, true.B)
// println("Warning, TxEnd no confident\n")
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
val txCnt = for( i <- 0 until 2 ) yield { Reg(UInt(2.W)) }
val txData = for( i <- 0 until 2 ) yield { Reg(UInt(32.W)) }
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
for( i <- 0 until 2 ) {
when( txFifo(i).io.deq.fire ){ //txCnt(i) === 3.U
txData(i) := txFifo(i).io.deq.bits
when( isTxBusy(i) ){
assert(CDROut(i).io.axis.fire)
}
} .elsewhen( CDROut(i).io.axis.fire ){
txData(i) := txData(i) << 8
}
txFifo(i).io.deq.ready :=
isTxFifoRelease(i) & Mux( isTxBusy(i), CDROut(i).io.axis.fire & txCnt(i) === 3.U, true.B )
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
txFifo(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
CDROut(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
CDROut(i).io.axis.bits.tdata := txData(i).head(8)
CDROut(i).io.axis.bits.tlast := ~txFifo(i).io.deq.valid & txCnt(i) === 3.U
CDROut(i).io.axis.bits.tuser := false.B
CDROut(i).io.axis.valid := isTxBusy(i)
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
when( isTLWriteSoftReset(i) ){
isTxBusy(i) := false.B
}.elsewhen( txFifo(i).io.deq.fire & ~isTxBusy(i) ){
isTxBusy(i) := true.B
} .elsewhen( CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast ){
isTxBusy(i) := false.B
}
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
when( isTLWriteSoftReset(0+i) ){
txCnt(i) := 0.U
} .elsewhen( CDROut(i).io.axis.fire ){
txCnt(i) := txCnt(i) + 1.U
}
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
when( isTLWriteTxLen(i) ){
txLen(i) := io.tla.bits.data
} .elsewhen( CDROut(i).io.axis.fire ){
txLen(i) := txLen(i) - 1.U
}
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
txFifo(i).io.enq.bits := io.tla.bits.data
txFifo(i).io.enq.valid := isTLWriteTxFifo(i) & txLen(i) =/= 0.U
2025-01-09 19:10:07 +08:00
}
}
trait TL2CDRRx{ this: TL2CDRBase =>
2025-02-05 18:06:52 +08:00
val isTLReadRxLen = for( i <- 0 until 2 ) yield { Wire(Bool()) }//io.tla.fire & io.tla.bits.address(5,0) === "h18".U & ( io.tla.bits.opcode === 4.U )
val isTLReadRxFifo = for( i <- 0 until 2 ) yield { Wire(Bool()) }//io.tla.fire & io.tla.bits.address(5,0) === "h1c".U & ( io.tla.bits.opcode === 4.U )
val rxLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
val isRxValid = for( i <- 0 until 2 ) yield { rxFifo(i).io.enq.fire }
val isRxError = for( i <- 0 until 2 ) yield { RegInit(false.B) }
val isAxisEnd = for( i <- 0 until 2 ) yield { RegInit(false.B) }
val isRxEnd = for( i <- 0 until 2 ) yield { isAxisEnd(i) & ~rxFifo(i).io.deq.valid }
val intRxError = for( i <- 0 until 2 ) yield { ~RegNext(isRxError(i), false.B) & isRxError(i) }
val intRxStart = for( i <- 0 until 2 ) yield { rxLen(i) === 0.U & CDRIn(i).io.axis.fire }
val intRxEnd = for( i <- 0 until 2 ) yield { ~RegNext(isRxEnd(i), false.B) & isRxEnd(i) }
val rxCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(2.W)) }
val rxData = for( i <- 0 until 2 ) yield { Reg(UInt(24.W)) }
for( i <- 0 until 2 ) {
when( isTLWriteSoftReset(2+i) ){
isAxisEnd(i) := false.B
} .elsewhen( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast ){
isAxisEnd(i) := true.B
}
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
when( isTLWriteSoftReset(2+i) ){
rxCnt(i) := 0.U
} .elsewhen( CDRIn(i).io.axis.fire ){
rxCnt(i) := rxCnt(i) + 1.U
rxData(i) := Cat( rxData(i), CDRIn(i).io.axis.bits.tdata )
}
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
when( isTLWriteSoftReset(2+i) ){
rxLen(i) := 0.U
} .elsewhen( CDRIn(i).io.axis.fire ){
rxLen(i) := rxLen(i) + 1.U
}
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
rxFifo(i).io.enq.valid := CDRIn(i).io.axis.fire & rxCnt(i) === 3.U
rxFifo(i).io.enq.bits := Cat( rxData(i)(23, 0) , CDRIn(i).io.axis.bits.tdata )
assert( ~(( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast) & rxCnt(i) =/= 3.U), "Assert Failed! Rx must 4-byte Align!" )
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
CDRIn(i).io.axis.ready := true.B
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
rxFifo(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
CDRIn(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
rxFifo(i).io.deq.ready := isTLReadRxFifo(i)
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
when( isTLWriteSoftReset(2+i) ){
isRxError(i) := false.B
} .elsewhen( rxFifo(i).io.enq.valid & ~rxFifo(i).io.enq.ready ){
isRxError(i) := true.B
printf(s"Warning, RxFifo$i Overflow!\n")
}
2025-01-09 19:10:07 +08:00
}
}
2025-01-16 17:57:44 +08:00
trait TL2CDRIsLast{ this: TL2CDRBase =>
io.isOnline := false.B
2025-02-05 18:06:52 +08:00
val isReadIsLast = Wire(Bool())//io.tla.fire & io.tla.bits.address(5,0) === "h20".U & io.tla.bits.opcode === 4.U
2025-01-16 17:57:44 +08:00
}
2025-01-24 16:01:10 +08:00
trait TL2CDRUserCRC{ this: TL2CDRBase =>
2025-02-05 18:06:52 +08:00
val isTLWriteTxFifo: Seq[Bool]
val isTLReadRxFifo: Seq[Bool]
val isTLReadTxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) } //io.tla.fire & io.tla.bits.address(5,0) === "h24".U & io.tla.bits.opcode === 4.U
val isTLReadRxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) } //io.tla.fire & io.tla.bits.address(5,0) === "h28".U & io.tla.bits.opcode === 4.U
2025-01-24 16:01:10 +08:00
2025-02-05 18:06:52 +08:00
val txCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
val rxCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
2025-01-24 16:01:10 +08:00
2025-02-05 18:06:52 +08:00
for( i <- 0 until 2 ) {
txCrc(i).io.enq.valid := isTLWriteTxFifo(i)
txCrc(i).io.enq.bits := io.tla.bits.data
2025-01-24 16:01:10 +08:00
2025-02-05 18:06:52 +08:00
rxCrc(i).io.enq.valid := isTLReadRxFifo(i)
rxCrc(i).io.enq.bits := rxFifo(i).io.deq.bits
2025-01-24 16:01:10 +08:00
2025-02-05 18:06:52 +08:00
txCrc(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
rxCrc(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
}
2025-01-24 16:01:10 +08:00
}
2025-01-27 22:26:26 +08:00
trait TL2CDRLimitTimmer{ this: TL2CDRBase =>
2025-02-05 18:06:52 +08:00
val intRxStart: Seq[Bool]
val isTLWriteSoftReset: Seq[Bool]
val isTxFifoRelease: Seq[Bool]
val isTLWriteLimitTimerAim = for( i <- 0 until 2 ) yield { Wire(Bool()) } //io.tla.fire & io.tla.bits.address(5,0) === "h2c".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
val isTLWriteLimitTxPair = for( i <- 0 until 2 ) yield { Wire(Bool()) }
val limitTimerCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
val limitTimerAim = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
val isLimitTimerTrigger = for( i <- 0 until 2 ) yield { RegInit(false.B) }
val txPairSel = for( i <- 0 until 2 ) yield { RegInit((i.U)(2.W)) }
for( i <- 0 until 2 ){
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
limitTimerCnt(i) := 0.U
} .elsewhen( limitTimerCnt(i) =/= limitTimerAim(i) ){
when( isLimitTimerTrigger(i) ){
limitTimerCnt(i) := limitTimerCnt(i) + 1.U
}
}
2025-01-27 22:26:26 +08:00
2025-02-05 18:06:52 +08:00
when( isTLWriteLimitTimerAim(i) ){
limitTimerAim(i) := io.tla.bits.data
}
2025-01-27 22:26:26 +08:00
2025-02-05 18:06:52 +08:00
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
isLimitTimerTrigger(i) := false.B
} .elsewhen( intRxStart(i) ){
isLimitTimerTrigger(i) := true.B
2025-01-27 22:26:26 +08:00
}
2025-02-05 18:06:52 +08:00
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
txPairSel(i) := i.U
} .elsewhen( isTLWriteLimitTxPair(i) ){
txPairSel(i) := io.tla.bits.data
}
2025-01-24 16:01:10 +08:00
2025-01-27 22:26:26 +08:00
2025-02-05 18:06:52 +08:00
isTxFifoRelease(i) := ( 0 until 2).map{ lmt =>
((txPairSel(lmt) =/= i.U) | (limitTimerCnt(lmt) === limitTimerAim(lmt)))
}.reduce(_&_)
2025-01-27 22:26:26 +08:00
2025-02-05 18:06:52 +08:00
}
2025-01-27 22:26:26 +08:00
}
2025-01-24 16:01:10 +08:00
2025-01-16 17:57:44 +08:00
class TL2CDR(edge: TLEdgeIn)(implicit p: Parameters) extends TL2CDRBase(edge)
with TL2CDRTx with TL2CDRRx
with TL2CDRIsLast
2025-01-24 16:01:10 +08:00
with TL2CDRUserCRC
2025-01-27 22:26:26 +08:00
with TL2CDRLimitTimmer
2025-01-16 17:57:44 +08:00
{
2025-01-09 19:10:07 +08:00
2025-02-05 18:06:52 +08:00
isTLWriteSoftReset(0) := io.tla.fire & io.tla.bits.address(5,0) === "h00".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLWriteTxLen(0) := io.tla.fire & io.tla.bits.address(5,0) === "h04".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLWriteTxFifo(0) := io.tla.fire & io.tla.bits.address(5,0) === "h08".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLReadTxCrc(0) := io.tla.fire & io.tla.bits.address(5,0) === "h0c".U & io.tla.bits.opcode === 4.U
isTLWriteSoftReset(1) := io.tla.fire & io.tla.bits.address(5,0) === "h10".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLWriteTxLen(1) := io.tla.fire & io.tla.bits.address(5,0) === "h14".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLWriteTxFifo(1) := io.tla.fire & io.tla.bits.address(5,0) === "h18".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLReadTxCrc(1) := io.tla.fire & io.tla.bits.address(5,0) === "h1c".U & io.tla.bits.opcode === 4.U
isTLWriteSoftReset(2) := io.tla.fire & io.tla.bits.address(5,0) === "h20".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLReadRxLen(0) := io.tla.fire & io.tla.bits.address(5,0) === "h24".U & ( io.tla.bits.opcode === 4.U )
isTLReadRxFifo(0) := io.tla.fire & io.tla.bits.address(5,0) === "h28".U & ( io.tla.bits.opcode === 4.U )
isTLReadRxCrc(0) := io.tla.fire & io.tla.bits.address(5,0) === "h2c".U & io.tla.bits.opcode === 4.U
isTLWriteLimitTimerAim(0) := io.tla.fire & io.tla.bits.address(5,0) === "h30".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLWriteLimitTxPair(0) := io.tla.fire & io.tla.bits.address(5,0) === "h34".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLWriteSoftReset(3) := io.tla.fire & io.tla.bits.address(5,0) === "h40".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLReadRxLen(1) := io.tla.fire & io.tla.bits.address(5,0) === "h44".U & ( io.tla.bits.opcode === 4.U )
isTLReadRxFifo(1) := io.tla.fire & io.tla.bits.address(5,0) === "h48".U & ( io.tla.bits.opcode === 4.U )
isTLReadRxCrc(1) := io.tla.fire & io.tla.bits.address(5,0) === "h4c".U & io.tla.bits.opcode === 4.U
isTLWriteLimitTimerAim(1) := io.tla.fire & io.tla.bits.address(5,0) === "h50".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLWriteLimitTxPair(1) := io.tla.fire & io.tla.bits.address(5,0) === "h54".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
isTLReadStatus := io.tla.fire & io.tla.bits.address(5,0) === "h58".U & ( io.tla.bits.opcode === 4.U )
isReadIsLast := io.tla.fire & io.tla.bits.address(5,0) === "h5c".U & ( io.tla.bits.opcode === 4.U )
io.interrupt(0) := intTxFinish(0)
io.interrupt(1) := intTxFinish(1)
io.interrupt(2) := intRxError(0)
io.interrupt(3) := intRxError(1)
io.interrupt(4) := intRxStart(0)
io.interrupt(5) := intRxStart(1)
io.interrupt(6) := intRxEnd(0)
io.interrupt(7) := intRxEnd(1)
2025-01-09 19:10:07 +08:00
val tlaInfo = Reg(new TLBundleA(edge.bundle))
val rdata = Reg(UInt(32.W))
val tlAReady = RegInit(true.B)
val tlDValid = RegInit(false.B)
val isRead = tlaInfo.opcode === 4.U
2025-02-05 18:06:52 +08:00
io.tla.ready :=
tlAReady &
MuxCase( true.B, Array(
( io.tla.bits.address(5,0) === "h08".U ) -> txFifo(0).io.enq.ready,
( io.tla.bits.address(5,0) === "h18".U ) -> txFifo(1).io.enq.ready,
( io.tla.bits.address(7,0) === "h28".U ) -> rxFifo(0).io.deq.valid,
( io.tla.bits.address(7,0) === "h48".U ) -> rxFifo(1).io.deq.valid,
))
io.tld.valid := tlDValid
2025-01-09 19:10:07 +08:00
when( io.tla.fire ) {
tlaInfo := io.tla.bits
}
when( io.tla.fire ){
tlAReady := false.B
tlDValid := true.B
} .elsewhen( io.tld.fire ) {
tlAReady := true.B
tlDValid := false.B
}
when(isRead) {
io.tld.bits := edge.AccessAck(tlaInfo, rdata)
} .otherwise {
io.tld.bits := edge.AccessAck(tlaInfo)
}
2025-02-05 18:06:52 +08:00
when( isTLReadStatus ){
rdata := Cat( isRxValid(1), isRxValid(0), isRxError(1), isRxError(0), isTxBusy(1), isTxBusy(0), isTxFull(1), isTxFull(0) )
} .elsewhen(isTLReadRxLen(0) ){
rdata := rxLen(0)
} .elsewhen(isTLReadRxLen(1) ){
rdata := rxLen(1)
} .elsewhen(isTLReadRxFifo(0) ){
rdata := rxFifo(0).io.deq.bits
} .elsewhen(isTLReadRxFifo(1) ){
rdata := rxFifo(1).io.deq.bits
2025-01-16 17:57:44 +08:00
} .elsewhen(isReadIsLast){
rdata := io.isLast
2025-02-05 18:06:52 +08:00
} .elsewhen(isTLReadTxCrc(0)){
rdata := txCrc(0).io.crc
} .elsewhen(isTLReadTxCrc(1)){
rdata := txCrc(1).io.crc
} .elsewhen(isTLReadRxCrc(0)){
rdata := rxCrc(0).io.crc
} .elsewhen(isTLReadRxCrc(1)){
rdata := rxCrc(1).io.crc
2025-01-09 19:10:07 +08:00
}
2025-01-27 22:26:26 +08:00
2025-01-09 19:10:07 +08:00
}