4个CDR上下行分离
This commit is contained in:
@@ -45,7 +45,7 @@ abstract class TL2CDRBase(val edge: TLEdgeIn)(implicit p: Parameters) extends Ba
|
||||
val tla = Flipped(new DecoupledIO(new TLBundleA(edge.bundle)))
|
||||
val tld = new DecoupledIO(new TLBundleD(edge.bundle))
|
||||
|
||||
val interrupt = Output(Vec(4, Bool()))
|
||||
val interrupt = Output(Vec(8, Bool()))
|
||||
|
||||
val isOnline = Output(Bool())
|
||||
val isLast = Input(Bool())
|
||||
@@ -53,107 +53,98 @@ abstract class TL2CDRBase(val edge: TLEdgeIn)(implicit p: Parameters) extends Ba
|
||||
|
||||
val io: TLCDRIO = IO(new TLCDRIO)
|
||||
|
||||
val dirSel = RegInit(false.B)
|
||||
val CDRIn = for( i <- 0 until 2 ) yield { Module(new CDRIn) }
|
||||
|
||||
val CDRIn = Module(new CDRIn)
|
||||
CDRIn.io.serDat := Mux( ~dirSel, io.dDatIn, io.uDatIn )
|
||||
CDRIn.io.overCLK := io.overCLK
|
||||
CDRIn(0).io.serDat := io.dDatIn
|
||||
CDRIn(1).io.serDat := io.uDatIn
|
||||
|
||||
val CDROut = Module(new CDROut)
|
||||
io.dDatOut := ~dirSel & CDROut.io.serDat
|
||||
io.uDatOut := dirSel & CDROut.io.serDat
|
||||
CDRIn(0).io.overCLK := io.overCLK
|
||||
CDRIn(1).io.overCLK := io.overCLK
|
||||
|
||||
val CDROut = for( i <- 0 until 2 ) yield { Module(new CDROut) }
|
||||
|
||||
io.dDatOut := CDROut(0).io.serDat
|
||||
io.uDatOut := CDROut(1).io.serDat
|
||||
|
||||
val txFifo = Module(new Queue(UInt(32.W), 16))
|
||||
val rxFifo = Module(new Queue(UInt(32.W), 16))
|
||||
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)) }
|
||||
|
||||
|
||||
// val isTLWriteSoftReset = io.mem.fire & io.mem.addr(5,0) === "h10".U & ( (io.mem.wstrb =/= 0.U) )
|
||||
val isTLWriteSoftReset = io.tla.fire & io.tla.bits.address(5,0) === "h10".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
|
||||
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 )
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait TL2CDRTx{ this: TL2CDRBase =>
|
||||
val isTxFifoRelease = Wire(Bool())
|
||||
// val isTLReadStatus = io.mem.fire & io.mem.addr(5,0) === "h0".U & ( io.mem.wstrb === 0.U )
|
||||
// val isTLWriteTxLen = io.mem.fire & io.mem.addr(5,0) === "h4".U & ( io.mem.wstrb =/= 0.U )
|
||||
// val isTLWriteTxFifo = io.mem.fire & io.mem.addr(5,0) === "h8".U & ( io.mem.wstrb =/= 0.U )
|
||||
val isTLReadStatus = io.tla.fire & io.tla.bits.address(5,0) === "h0".U & ( io.tla.bits.opcode === 4.U )
|
||||
val isTLWriteTxLen = 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 = io.tla.fire & io.tla.bits.address(5,0) === "h8".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
|
||||
|
||||
|
||||
val txLen = RegInit(0.U(12.W))
|
||||
val isTxBusy = RegInit(false.B)
|
||||
val isTxFull = ~txFifo.io.enq.ready
|
||||
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) )
|
||||
|
||||
|
||||
val intTxEnd = ShiftRegister( CDROut.io.axis.fire & CDROut.io.axis.bits.tlast, 5, false.B, true.B)
|
||||
println("Warning, TxEnd no confident\n")
|
||||
val intTxFifoFull = ~RegNext(isTxFull, false.B) & isTxFull
|
||||
val intTxFinish = CDROut.io.axis.fire & CDROut.io.axis.bits.tlast
|
||||
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 }
|
||||
|
||||
val txCnt = Reg(UInt(2.W))
|
||||
|
||||
val txData = Reg(UInt(32.W))
|
||||
// val intTxEnd = ShiftRegister( CDROut.io.axis.fire & CDROut.io.axis.bits.tlast, 5, false.B, true.B)
|
||||
// println("Warning, TxEnd no confident\n")
|
||||
|
||||
when( txFifo.io.deq.fire ){ //txCnt === 3.U
|
||||
txData := txFifo.io.deq.bits
|
||||
when( isTxBusy ){
|
||||
assert(CDROut.io.axis.fire)
|
||||
|
||||
val txCnt = for( i <- 0 until 2 ) yield { Reg(UInt(2.W)) }
|
||||
val txData = for( i <- 0 until 2 ) yield { Reg(UInt(32.W)) }
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
} .elsewhen( CDROut.io.axis.fire ){
|
||||
txData := txData << 8
|
||||
txFifo(i).io.deq.ready :=
|
||||
isTxFifoRelease(i) & Mux( isTxBusy(i), CDROut(i).io.axis.fire & txCnt(i) === 3.U, true.B )
|
||||
|
||||
txFifo(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
CDROut(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
txCnt(i) := 0.U
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txCnt(i) := txCnt(i) + 1.U
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteTxLen(i) ){
|
||||
txLen(i) := io.tla.bits.data
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txLen(i) := txLen(i) - 1.U
|
||||
}
|
||||
|
||||
txFifo(i).io.enq.bits := io.tla.bits.data
|
||||
txFifo(i).io.enq.valid := isTLWriteTxFifo(i) & txLen(i) =/= 0.U
|
||||
}
|
||||
|
||||
txFifo.io.deq.ready :=
|
||||
isTxFifoRelease & Mux( isTxBusy, CDROut.io.axis.fire & txCnt === 3.U, true.B )
|
||||
|
||||
txFifo.reset := reset.asBool | isTLWriteTxLen | isTLWriteSoftReset
|
||||
CDROut.reset := reset.asBool | isTLWriteTxLen | isTLWriteSoftReset
|
||||
|
||||
CDROut.io.axis.bits.tdata := txData.head(8)
|
||||
|
||||
// PriorityMux(Seq(
|
||||
// (txCnt === 0.U) -> txData(31, 24),
|
||||
// (txCnt === 1.U) -> txData(23, 16),
|
||||
// (txCnt === 2.U) -> txData(15, 8),
|
||||
// (txCnt === 3.U) -> txData( 7, 0),
|
||||
// ))
|
||||
|
||||
CDROut.io.axis.bits.tlast := ~txFifo.io.deq.valid & txCnt === 3.U
|
||||
CDROut.io.axis.bits.tuser := false.B
|
||||
CDROut.io.axis.valid := isTxBusy
|
||||
|
||||
|
||||
when( isTLWriteTxLen | isTLWriteSoftReset ){
|
||||
isTxBusy := false.B
|
||||
}.elsewhen( txFifo.io.deq.fire & ~isTxBusy ){
|
||||
isTxBusy := true.B
|
||||
} .elsewhen( CDROut.io.axis.fire & CDROut.io.axis.bits.tlast ){
|
||||
isTxBusy := false.B
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteTxLen ){
|
||||
txCnt := 0.U
|
||||
} .elsewhen( CDROut.io.axis.fire ){
|
||||
txCnt := txCnt + 1.U
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteTxLen ){
|
||||
// txLen := io.mem.wdata
|
||||
txLen := io.tla.bits.data
|
||||
} .elsewhen( CDROut.io.axis.fire ){
|
||||
txLen := txLen - 1.U
|
||||
}
|
||||
|
||||
txFifo.io.enq.bits := io.tla.bits.data
|
||||
txFifo.io.enq.valid := isTLWriteTxFifo & txLen =/= 0.U
|
||||
|
||||
|
||||
}
|
||||
@@ -161,137 +152,144 @@ trait TL2CDRTx{ this: TL2CDRBase =>
|
||||
|
||||
trait TL2CDRRx{ this: TL2CDRBase =>
|
||||
|
||||
// val isTLReadRxStatus = io.mem.fire & io.mem.addr(5,0) === "h14".U & ( io.mem.wstrb === 0.U )
|
||||
// val isTLReadRxLen = io.mem.fire & io.mem.addr(5,0) === "h18".U & ( io.mem.wstrb === 0.U )
|
||||
// val isTLReadRxFifo = io.mem.fire & io.mem.addr(5,0) === "h1c".U & ( io.mem.wstrb === 0.U )
|
||||
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 isTLReadRxStatus = io.tla.fire & io.tla.bits.address(5,0) === "h14".U & ( io.tla.bits.opcode === 4.U )
|
||||
val isTLReadRxLen = io.tla.fire & io.tla.bits.address(5,0) === "h18".U & ( io.tla.bits.opcode === 4.U )
|
||||
val isTLReadRxFifo = 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
|
||||
}
|
||||
|
||||
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 )
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxLen(i) := 0.U
|
||||
} .elsewhen( CDRIn(i).io.axis.fire ){
|
||||
rxLen(i) := rxLen(i) + 1.U
|
||||
}
|
||||
|
||||
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!" )
|
||||
|
||||
CDRIn(i).io.axis.ready := true.B
|
||||
|
||||
rxFifo(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
CDRIn(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
|
||||
rxFifo(i).io.deq.ready := isTLReadRxFifo(i)
|
||||
|
||||
|
||||
val rxLen = RegInit(0.U(12.W))
|
||||
val isRxValid = rxFifo.io.enq.fire
|
||||
val isRxError = RegInit(false.B)
|
||||
val isAxisEnd = RegInit(false.B)
|
||||
val isRxEnd = isAxisEnd & ~rxFifo.io.deq.valid
|
||||
|
||||
val intRxError = ~RegNext(isRxError, false.B) & isRxError
|
||||
val intRxStart = rxLen === 0.U & CDRIn.io.axis.fire
|
||||
val intRxEnd = ~RegNext(isRxEnd, false.B) & isRxEnd
|
||||
|
||||
|
||||
val rxCnt = RegInit(0.U(2.W))
|
||||
val rxData = Reg(UInt(24.W))
|
||||
|
||||
when( isTLWriteSoftReset ){
|
||||
isAxisEnd := false.B
|
||||
} .elsewhen( CDRIn.io.axis.fire & CDRIn.io.axis.bits.tlast ){
|
||||
isAxisEnd := true.B
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteSoftReset ){
|
||||
rxCnt := 0.U
|
||||
} .elsewhen( CDRIn.io.axis.fire ){
|
||||
rxCnt := rxCnt + 1.U
|
||||
|
||||
rxData := Cat( rxData, CDRIn.io.axis.bits.tdata )
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset ){
|
||||
rxLen := 0.U
|
||||
} .elsewhen( CDRIn.io.axis.fire ){
|
||||
rxLen := rxLen + 1.U
|
||||
}
|
||||
|
||||
rxFifo.io.enq.valid := CDRIn.io.axis.fire & rxCnt === 3.U
|
||||
rxFifo.io.enq.bits := Cat( rxData(23, 0) , CDRIn.io.axis.bits.tdata )
|
||||
|
||||
assert( ~(( CDRIn.io.axis.fire & CDRIn.io.axis.bits.tlast) & rxCnt =/= 3.U), "Assert Failed! Rx must 4-byte Align!" )
|
||||
|
||||
CDRIn.io.axis.ready := true.B
|
||||
|
||||
rxFifo.reset := reset.asBool | isTLWriteSoftReset
|
||||
CDRIn.reset := reset.asBool | isTLWriteSoftReset
|
||||
|
||||
rxFifo.io.deq.ready := isTLReadRxFifo
|
||||
|
||||
|
||||
when( isTLWriteSoftReset ){
|
||||
isRxError := false.B
|
||||
} .elsewhen( rxFifo.io.enq.valid & ~rxFifo.io.enq.ready ){
|
||||
isRxError := true.B
|
||||
printf("Warning, RxFifo Overflow!\n")
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRIsLast{ this: TL2CDRBase =>
|
||||
io.isOnline := false.B
|
||||
val isReadIsLast = io.tla.fire & io.tla.bits.address(5,0) === "h20".U & io.tla.bits.opcode === 4.U
|
||||
val isReadIsLast = Wire(Bool())//io.tla.fire & io.tla.bits.address(5,0) === "h20".U & io.tla.bits.opcode === 4.U
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRUserCRC{ this: TL2CDRBase =>
|
||||
val isTLWriteTxFifo: Bool
|
||||
val isTLReadRxFifo: Bool
|
||||
val isTLWriteTxFifo: Seq[Bool]
|
||||
val isTLReadRxFifo: Seq[Bool]
|
||||
|
||||
val isTLReadTxCrc = io.tla.fire & io.tla.bits.address(5,0) === "h24".U & io.tla.bits.opcode === 4.U
|
||||
val isTLReadRxCrc = io.tla.fire & io.tla.bits.address(5,0) === "h28".U & io.tla.bits.opcode === 4.U
|
||||
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
|
||||
|
||||
|
||||
val txCrc = Module(new crc32_32)
|
||||
val rxCrc = Module(new crc32_32)
|
||||
val txCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
val rxCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
|
||||
txCrc.io.enq.valid := isTLWriteTxFifo
|
||||
txCrc.io.enq.bits := io.tla.bits.data
|
||||
for( i <- 0 until 2 ) {
|
||||
txCrc(i).io.enq.valid := isTLWriteTxFifo(i)
|
||||
txCrc(i).io.enq.bits := io.tla.bits.data
|
||||
|
||||
rxCrc.io.enq.valid := isTLReadRxFifo
|
||||
rxCrc.io.enq.bits := rxFifo.io.deq.bits
|
||||
rxCrc(i).io.enq.valid := isTLReadRxFifo(i)
|
||||
rxCrc(i).io.enq.bits := rxFifo(i).io.deq.bits
|
||||
|
||||
txCrc(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
rxCrc(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
}
|
||||
|
||||
txCrc.reset := reset.asBool | isTLWriteSoftReset
|
||||
rxCrc.reset := reset.asBool | isTLWriteSoftReset
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRLimitTimmer{ this: TL2CDRBase =>
|
||||
val intRxStart: Bool
|
||||
val isTLWriteSoftReset: Bool
|
||||
val isTLWriteLimitTimerAim = io.tla.fire & io.tla.bits.address(5,0) === "h2c".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
|
||||
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 = RegInit(0.U(16.W))
|
||||
val limitTimerAim = RegInit(0.U(16.W))
|
||||
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)) }
|
||||
|
||||
val isLimitTimerTrigger = RegInit(false.B)
|
||||
|
||||
when( isTLWriteSoftReset ){
|
||||
limitTimerCnt := 0.U
|
||||
} .elsewhen( limitTimerCnt =/= limitTimerAim ){
|
||||
when( isLimitTimerTrigger ){
|
||||
limitTimerCnt := limitTimerCnt + 1.U
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
when( isTLWriteLimitTimerAim(i) ){
|
||||
limitTimerAim(i) := io.tla.bits.data
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
isLimitTimerTrigger(i) := false.B
|
||||
} .elsewhen( intRxStart(i) ){
|
||||
isLimitTimerTrigger(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
txPairSel(i) := i.U
|
||||
} .elsewhen( isTLWriteLimitTxPair(i) ){
|
||||
txPairSel(i) := io.tla.bits.data
|
||||
}
|
||||
|
||||
|
||||
isTxFifoRelease(i) := ( 0 until 2).map{ lmt =>
|
||||
((txPairSel(lmt) =/= i.U) | (limitTimerCnt(lmt) === limitTimerAim(lmt)))
|
||||
}.reduce(_&_)
|
||||
|
||||
}
|
||||
|
||||
when( isTLWriteLimitTimerAim ){
|
||||
limitTimerAim := io.tla.bits.data
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset ){
|
||||
isLimitTimerTrigger := false.B
|
||||
} .elsewhen( intRxStart ){
|
||||
isLimitTimerTrigger := true.B
|
||||
}
|
||||
|
||||
val isTxFifoRelease: Bool
|
||||
isTxFifoRelease := limitTimerCnt === limitTimerAim
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -308,8 +306,47 @@ with TL2CDRUserCRC
|
||||
with TL2CDRLimitTimmer
|
||||
{
|
||||
|
||||
// val isWriteTransDir = io.mem.fire & io.mem.addr(5,0) === "hc".U & io.mem.wstrb =/= 0.U
|
||||
val isWriteTransDir = io.tla.fire & io.tla.bits.address(5,0) === "hc".U & ( (io.tla.bits.opcode === 0.U) || (io.tla.bits.opcode === 1.U) )
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
val tlaInfo = Reg(new TLBundleA(edge.bundle))
|
||||
val rdata = Reg(UInt(32.W))
|
||||
@@ -318,30 +355,24 @@ with TL2CDRLimitTimmer
|
||||
|
||||
val isRead = tlaInfo.opcode === 4.U
|
||||
|
||||
when( isWriteTransDir ){
|
||||
// dirSel := io.mem.wdata
|
||||
dirSel := io.tla.bits.data
|
||||
}
|
||||
|
||||
// io.mem.ready :=
|
||||
// ( io.mem.wstrb =/= 0.U & txFifo.io.enq.ready) |
|
||||
// ( io.mem.wstrb === 0.U & Mux( io.mem.addr(5,0) === "h1c".U, rxFifo.io.deq.valid, true.B ) )
|
||||
|
||||
io.tla.ready := tlAReady & txFifo.io.enq.ready & ( Mux(io.tla.bits.address(5,0) === "h1c".U & ( io.tla.bits.opcode === 4.U ), rxFifo.io.deq.valid, true.B) )
|
||||
|
||||
|
||||
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
|
||||
|
||||
io.interrupt(0) := intTxEnd
|
||||
io.interrupt(1) := intRxError
|
||||
io.interrupt(2) := intRxStart
|
||||
io.interrupt(3) := intRxEnd
|
||||
|
||||
|
||||
// io.mem.rdata :=
|
||||
// Mux1H(Seq(
|
||||
// isTLReadStatus -> Cat( isRxValid, isRxError, isTxBusy, isTxFull, false.B),
|
||||
// isTLReadRxLen -> rxLen,
|
||||
// isTLReadRxFifo -> rxFifo.io.deq.bits
|
||||
// ))
|
||||
|
||||
when( io.tla.fire ) {
|
||||
tlaInfo := io.tla.bits
|
||||
@@ -361,18 +392,27 @@ with TL2CDRLimitTimmer
|
||||
io.tld.bits := edge.AccessAck(tlaInfo)
|
||||
}
|
||||
|
||||
when( isTLReadStatus){
|
||||
rdata := Cat( isRxValid, isRxError, isTxBusy, isTxFull, false.B )
|
||||
} .elsewhen(isTLReadRxLen ){
|
||||
rdata := rxLen
|
||||
} .elsewhen(isTLReadRxFifo ){
|
||||
rdata := rxFifo.io.deq.bits
|
||||
|
||||
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
|
||||
} .elsewhen(isReadIsLast){
|
||||
rdata := io.isLast
|
||||
} .elsewhen(isTLReadTxCrc){
|
||||
rdata := txCrc.io.crc
|
||||
} .elsewhen(isTLReadRxCrc){
|
||||
rdata := rxCrc.io.crc
|
||||
} .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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user