hack 入,但io如何扇出到顶层?

Revert "hack 入,但io如何扇出到顶层?"

This reverts commit 04dd4dff462b8986d18d13ee7c6b3f17caad247c.

Revert "Revert "hack 入,但io如何扇出到顶层?""

This reverts commit a2fadc0e5524cd292ed245f1fbb5f4a688d95a1d.

CDRIN成功扇出

Rocc仿真环境

扇出RoCC请求返回的FIFO

Revert "扇出RoCC请求返回的FIFO"

This reverts commit c52777091403d300f19935df7b6de3d62c57430b.

RoCC请求返回FIFO使用FLOW模式
This commit is contained in:
Ruige Lee (WSL)
2025-02-13 18:14:26 +08:00
parent 8c3c0112fb
commit 522d7c19c6
2 changed files with 583 additions and 31 deletions

View File

@@ -0,0 +1,555 @@
package BACK
import chisel3._
import chisel3.util._
import org.chipsalliance.cde.config._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.interrupts._
import freechips.rocketchip.tile._
class RocCC2CDRInIO extends Bundle{
val overCLK = Bool()
val dDatIn = Bool()
val uDatIn = Bool()
val isLast = Bool()
}
class RocCC2CDROutIO extends Bundle{
val dDatOut = Bool()
val uDatOut = Bool()
val isOnline = Bool()
}
class RoCC2CDRIO extends Bundle{
val overCLK = Input(Bool())
val dDatIn = Input(Bool())
val dDatOut = Output(Bool())
val uDatIn = Input(Bool())
val uDatOut = Output(Bool())
val isOnline = Output(Bool())
val isLast = Input(Bool())
}
class RoCC2CDR()(implicit p: Parameters) extends LazyModule {
val opcodes: OpcodeSet = OpcodeSet.custom0
val roccCSRs: Seq[CustomCSR] = Nil
lazy val module: RoCC2CDRImpl = new RoCC2CDRImpl(this)
}
abstract class RoCC2CDRImplBase(outer: RoCC2CDR)(implicit p: Parameters) extends LazyModuleImp(outer) {
val io = IO(new RoCCIO(0, 0))
// val cdrio: RoCC2CDRIO = IO(new RoCC2CDRIO)
val cdrInio = IO(Input(new RocCC2CDRInIO))
val cdrOutio = IO(Output(new RocCC2CDROutIO))
val CDRIn = for( i <- 0 until 2 ) yield { Module(new CDRIn) }
CDRIn(0).io.serDat := cdrInio.dDatIn
CDRIn(1).io.serDat := cdrInio.uDatIn
CDRIn(0).io.overCLK := cdrInio.overCLK
CDRIn(1).io.overCLK := cdrInio.overCLK
val CDROut = for( i <- 0 until 2 ) yield { Module(new CDROut) }
cdrOutio.dDatOut := CDROut(0).io.serDat
cdrOutio.uDatOut := CDROut(1).io.serDat
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 = for( i <- 0 until 4 ) yield { Wire(Bool()) }
val isTLReadStatus = Wire( Bool() )
val txLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
val rxLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
val wdata = Wire(UInt(32.W))
}
trait RoCC2CDRImplTx{ this: RoCC2CDRImplBase =>
val isTLWriteTxLen = for( i <- 0 until 2 ) yield { Wire( Bool()) }
val isTLWriteTxFifo = for( i <- 0 until 2 ) yield { Wire( Bool()) }
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 intTxEnd = for( i <- 0 until 2 ) yield { ShiftRegister( intTxFinish(i), 6, false.B, true.B) }
val intTxFifoDeq = for( i <- 0 until 2 ) yield { txFifo(i).io.deq.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
}
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) := wdata
} .elsewhen( CDROut(i).io.axis.fire ){
txLen(i) := txLen(i) - 1.U
}
txFifo(i).io.enq.bits := wdata
txFifo(i).io.enq.valid := isTLWriteTxFifo(i) & txLen(i) =/= 0.U
when( isTLWriteSoftReset(0+i) ){
txLeft(i) := 0.U
} .elsewhen( txFifo(i).io.enq.fire & txFifo(i).io.deq.fire ){
txLeft(i) := txLeft(i)
} .elsewhen( txFifo(i).io.enq.fire ){
txLeft(i) := txLeft(i) + 1.U
} .elsewhen( txFifo(i).io.deq.fire ){
txLeft(i) := txLeft(i) - 1.U
}
}
}
trait RoCC2CDRImplRx{ this: RoCC2CDRImplBase =>
val isTLReadRxLen = for( i <- 0 until 2 ) yield { Wire(Bool()) }
val isTLReadRxFifo = for( i <- 0 until 2 ) yield { Wire(Bool()) }
val rxLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
val isRxValid = for( i <- 0 until 2 ) yield { rxFifo(i).io.deq.valid }
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 intRxFifoEnq = for( i <- 0 until 2 ) yield { rxFifo(i).io.enq.fire }
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)
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(2+i) ){
rxLeft(i) := 0.U
} .elsewhen( rxFifo(i).io.enq.fire & rxFifo(i).io.deq.fire ){
rxLeft(i) := rxLeft(i)
} .elsewhen( rxFifo(i).io.enq.fire ){
rxLeft(i) := rxLeft(i) + 1.U
} .elsewhen( rxFifo(i).io.deq.fire ){
rxLeft(i) := rxLeft(i) - 1.U
}
}
}
trait RoCC2CDRImplIsLast{ this: RoCC2CDRImplBase =>
cdrOutio.isOnline := false.B
val isReadIsLast = Wire(Bool())
}
trait RoCC2CDRImplUserCRC{ this: RoCC2CDRImplBase =>
val isTLWriteTxFifo: Seq[Bool]
val isTLReadRxFifo: Seq[Bool]
val isTLReadTxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
val isTLReadRxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
val txCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
val rxCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
for( i <- 0 until 2 ) {
txCrc(i).io.enq.valid := isTLWriteTxFifo(i)
txCrc(i).io.enq.bits := wdata
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)
}
}
trait RoCC2CDRImplLimitTimmer{ this: RoCC2CDRImplBase =>
val intRxStart: Seq[Bool]
val isTLWriteSoftReset: Seq[Bool]
val isTxFifoRelease: Seq[Bool]
val isTLWriteLimitTimerAim = for( i <- 0 until 2 ) yield { Wire(Bool()) }
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
}
}
when( isTLWriteLimitTimerAim(i) ){
limitTimerAim(i) := wdata
}
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) := wdata
}
isTxFifoRelease(i) := ( 0 until 2).map{ lmt =>
((txPairSel(lmt) =/= i.U) | (limitTimerCnt(lmt) === limitTimerAim(lmt)))
}.reduce(_&_)
}
}
class RoCC2CDRImpl(outer: RoCC2CDR)(implicit p: Parameters) extends RoCC2CDRImplBase(outer)
with RoCC2CDRImplTx with RoCC2CDRImplRx
with RoCC2CDRImplIsLast
with RoCC2CDRImplUserCRC
with RoCC2CDRImplLimitTimmer
{
io.mem.req.valid := false.B
io.mem.req.bits := DontCare
io.mem.s1_kill := false.B
io.mem.s1_data := DontCare
io.mem.s2_kill := false.B
io.mem.keep_clock_enabled := false.B
// io.interrupt = Output(Bool())
// io.exception = Input(Bool())
io.fpu_req.valid := false.B
io.fpu_req.bits := DontCare
io.fpu_resp.ready := true.B
isTLWriteSoftReset(0) := io.cmd.fire & io.cmd.bits.inst.funct === 0.U
isTLWriteTxLen(0) := io.cmd.fire & io.cmd.bits.inst.funct === 1.U
isTLWriteTxFifo(0) := io.cmd.fire & io.cmd.bits.inst.funct === 2.U
isTLReadTxCrc(0) := io.cmd.fire & io.cmd.bits.inst.funct === 3.U
isTLWriteSoftReset(1) := io.cmd.fire & io.cmd.bits.inst.funct === 4.U
isTLWriteTxLen(1) := io.cmd.fire & io.cmd.bits.inst.funct === 5.U
isTLWriteTxFifo(1) := io.cmd.fire & io.cmd.bits.inst.funct === 6.U
isTLReadTxCrc(1) := io.cmd.fire & io.cmd.bits.inst.funct === 7.U
isTLWriteSoftReset(2) := io.cmd.fire & io.cmd.bits.inst.funct === 8.U
isTLReadRxLen(0) := io.cmd.fire & io.cmd.bits.inst.funct === 9.U
isTLReadRxFifo(0) := io.cmd.fire & io.cmd.bits.inst.funct === 10.U
isTLReadRxCrc(0) := io.cmd.fire & io.cmd.bits.inst.funct === 11.U
isTLWriteLimitTimerAim(0) := io.cmd.fire & io.cmd.bits.inst.funct === 12.U
isTLWriteLimitTxPair(0) := io.cmd.fire & io.cmd.bits.inst.funct === 13.U
isTLWriteSoftReset(3) := io.cmd.fire & io.cmd.bits.inst.funct === 14.U
isTLReadRxLen(1) := io.cmd.fire & io.cmd.bits.inst.funct === 15.U
isTLReadRxFifo(1) := io.cmd.fire & io.cmd.bits.inst.funct === 16.U
isTLReadRxCrc(1) := io.cmd.fire & io.cmd.bits.inst.funct === 17.U
isTLWriteLimitTimerAim(1) := io.cmd.fire & io.cmd.bits.inst.funct === 18.U
isTLWriteLimitTxPair(1) := io.cmd.fire & io.cmd.bits.inst.funct === 19.U
isTLReadStatus := io.cmd.fire & io.cmd.bits.inst.funct === 20.U
isReadIsLast := io.cmd.fire & io.cmd.bits.inst.funct === 21.U
// int(0) := intTxEnd(0)
// int(1) := intTxEnd(1)
// int(2) := intRxError(0)
// int(3) := intRxError(1)
// int(4) := intRxStart(0)
// int(5) := intRxStart(1)
// int(6) := intRxEnd(0)
// int(7) := intRxEnd(1)
// int(8) := intTxFifoDeq(0)
// int(9) := intTxFifoDeq(1)
// int(10) := intRxFifoEnq(0)
// int(11) := intRxFifoEnq(1)
io.interrupt :=
intTxEnd(0) |
intTxEnd(1) |
intRxError(0) |
intRxError(1) |
intRxStart(0) |
intRxStart(1) |
intRxEnd(0) |
intRxEnd(1) |
intTxFifoDeq(0) |
intTxFifoDeq(1) |
intRxFifoEnq(0) |
intRxFifoEnq(1)
wdata := io.cmd.bits.rs1
val cmdInfo = RegEnable(io.cmd.bits, io.cmd.fire)
val rdata = Reg(UInt(32.W))
// val cmdReady = RegInit(true.B)
val respValid = RegInit(false.B)
io.busy := respValid
io.cmd.ready := ~respValid
io.resp.valid := respValid
io.resp.bits.rd := cmdInfo.inst.rd
io.resp.bits.data := rdata
printf("Warning, no protection on tx rx fifo!\n")
// MuxCase( true.B, Array(
// ( io.cmd.bits.inst.funct === 2.U ) -> txFifo(0).io.enq.ready,
// ( io.cmd.bits.inst.funct === 6.U ) -> txFifo(1).io.enq.ready,
// ( bus.a.bits.address(7,0) === "h28".U ) -> rxFifo(0).io.deq.valid,
// ( bus.a.bits.address(7,0) === "h48".U ) -> rxFifo(1).io.deq.valid,
// ))
when( isTLReadStatus ){
rdata := Cat( txLeft(1), txLeft(0), rxLeft(1), rxLeft(0), 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 := cdrInio.isLast
} .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
}
when( io.resp.fire ){ //允许连续触发
respValid := false.B
} .elsewhen( isTLReadStatus ){
respValid := true.B
} .elsewhen(isTLReadRxLen(0) ){
respValid := true.B
} .elsewhen(isTLReadRxLen(1) ){
respValid := true.B
} .elsewhen(isTLReadRxFifo(0) ){
respValid := true.B
} .elsewhen(isTLReadRxFifo(1) ){
respValid := true.B
} .elsewhen(isReadIsLast){
respValid := true.B
} .elsewhen(isTLReadTxCrc(0)){
respValid := true.B
} .elsewhen(isTLReadTxCrc(1)){
respValid := true.B
} .elsewhen(isTLReadRxCrc(0)){
respValid := true.B
} .elsewhen(isTLReadRxCrc(1)){
respValid := true.B
}
}
trait HasLazyRoCC2CDR { this: BaseTile =>
val roccs = LazyModule(new RoCC2CDR())
val roccCSRs = Seq(roccs.roccCSRs) // the set of custom CSRs requested by all roccs
}
trait HasLazyRoCC2CDRModule extends HasCoreParameters { this: RocketTileModuleImp with HasFpuOpt =>
// val (respArb, cmdRouter) = {
// val respArb = Module(new RRArbiter(new RoCCResponse()(outer.p), outer.roccs.size))
val cmdRouter = Module(new Queue( new RoCCCommand, 2, false, true ))//Module(new RoccCommandRouter( Seq(outer.roccs.opcodes) )(outer.p))
// outer.roccs.module.io.ptw ++=: ptwPorts
outer.roccs.module.io.cmd <> cmdRouter.io.deq
// val dcIF = Module(new SimpleHellaCacheIF()(outer.p))
// dcIF.io.requestor <> outer.roccs.module.io.mem
// dcachePorts += dcIF.io.cache
//respArb.io.in(0) <> Queue(outer.roccs.module.io.resp)
fpuOpt foreach { fpu =>
fpu.io.cp_req.valid := false.B
fpu.io.cp_resp.ready := false.B
}
// (Some(respArb), Some(cmdRouter))
// }
// val roccCSRIOs = Seq(outer.roccs.module.io.csrs)
// (core.io.rocc.csrs zip roccCSRIOs.flatten).foreach { t => t._2 := t._1 }
val cdrInio = IO(Input(new RocCC2CDRInIO))
val cdrOutio = IO(Output(new RocCC2CDROutIO))
// val cdrio: RoCC2CDRIO = IO(new RoCC2CDRIO)
// dontTouch(cdrio)
cdrInio <> outer.roccs.module.cdrInio
cdrOutio <> outer.roccs.module.cdrOutio
}