package BACK import chisel3._ import chisel3.util._ class ShinSlvIO_Bundle extends Bundle{ val isOnline = Output(Bool()) val isLast = Input(Bool()) val DCIn = Input(Bool()) val downSer = new Bundle{ val out = Output(Bool()) val in = Input(Bool()) } val upSer = new Bundle{ val out = Output(Bool()) val in = Input(Bool()) } val overCLK = Input(Bool()) } abstract class ShinSlvPhyBase extends Module{ val io: ShinSlvIO_Bundle = IO(new ShinSlvIO_Bundle) val downStreamCdrOut = Module(new CDROut with chisel3.util.experimental.InlineInstance) val downStreamCdrIn = Module(new CDRIn with chisel3.util.experimental.InlineInstance) val upStreamCdrOut = Module(new CDROut with chisel3.util.experimental.InlineInstance) val upStreamCdrIn = Module(new CDRIn with chisel3.util.experimental.InlineInstance) io.downSer.out := downStreamCdrOut.io.serDat downStreamCdrIn.io.serDat := io.downSer.in downStreamCdrIn.io.overCLK := io.overCLK io.upSer.out := upStreamCdrOut.io.serDat upStreamCdrIn.io.serDat := io.upSer.in upStreamCdrIn.io.overCLK := io.overCLK io.isOnline := true.B val downRegTemp = Reg(Vec( 32, UInt(8.W) )) val upReg = WireDefault(VecInit((0 until 32).map{i => 0.U(8.W)})) val headByte = (new Header_Info_Bundle).getWidth/8 require( headByte == 8 ) require( headByte > 4, "At Least 4 more additional cycles to ensure CRC Failure boardcast to next nodes!\n") val OpInitByte = 8 val OpBoardCastByte = 16 val OpUniCastByte = 32 val maxLocalByte = OpInitByte max OpBoardCastByte max OpUniCastByte val downForwardFifo = Module( new Queue( new AXIS_Bundle(8), 8 + headByte + 4 ) with chisel3.util.experimental.InlineInstance) val upForwardFifo = Module( new Queue( new AXIS_Bundle(8), headByte + maxLocalByte + 4 ) with chisel3.util.experimental.InlineInstance) //4 is reserve val isLastDevice = Wire(Bool()) } trait ShinSlvPhyDownStreamRecv{ this: ShinSlvPhyBase => val DownRecvStateIdle = 0.U val DownRecvStateOHead = 1.U val DownRecvStateSData = 2.U val DownRecvStateFData = 3.U val DownRecvStateCRC = 4.U val downOldHead = Reg( new Header_Info_Bundle ) val downNewHead = Reg( new Header_Info_Bundle ) val downNewHeadShift = Reg( new Header_Info_Bundle ) val downPendBuf= Module( new Queue( new AXIS_Bundle(8), 2, pipe = true, flow = false ) with chisel3.util.experimental.InlineInstance) downStreamCdrIn.io.axis <> downPendBuf.io.enq val downRecvStateNext = Wire( UInt(3.W) ) val downRecvStateCurr = RegNext( downRecvStateNext, 0.U ) val downRecvCnt = Reg(UInt(10.W)) val downLocalDataByte = RegEnable( Mux1H(Seq( ( downOldHead.asUInt(3,0) === 0.U) -> OpInitByte.U, ( downOldHead.asUInt(3,0) === 1.U) -> OpBoardCastByte.U, ( downOldHead.asUInt(3,0) === 2.U) -> OpUniCastByte.U, )), downRecvStateCurr === DownRecvStateOHead & downPendBuf.io.deq.fire & downRecvCnt === 3.U) //Timing Opt val isDownStreamError = RegInit( false.B ) val downForwardDataByte = downNewHead.length val isLastDevice: Bool downRecvStateNext := Mux1H(Seq( (downRecvStateCurr === DownRecvStateIdle ) -> Mux( downPendBuf.io.deq.valid, DownRecvStateOHead, DownRecvStateIdle ), (downRecvStateCurr === DownRecvStateOHead) -> Mux( downPendBuf.io.deq.fire, Mux( ~downPendBuf.io.deq.bits.tlast, Mux(downRecvCnt === ((headByte)).U, DownRecvStateSData, DownRecvStateOHead), DownRecvStateIdle ), DownRecvStateOHead), (downRecvStateCurr === DownRecvStateSData) -> Mux( downPendBuf.io.deq.fire, Mux( ~downPendBuf.io.deq.bits.tlast, Mux(downRecvCnt === (downLocalDataByte ), Mux( downRecvCnt === (downOldHead.length - 1.U), DownRecvStateCRC, DownRecvStateFData ), DownRecvStateSData), DownRecvStateIdle ), DownRecvStateSData), (downRecvStateCurr === DownRecvStateFData) -> Mux( downPendBuf.io.deq.fire, Mux( ~downPendBuf.io.deq.bits.tlast, Mux(downRecvCnt === (downForwardDataByte ) , DownRecvStateCRC, DownRecvStateFData), DownRecvStateIdle ), DownRecvStateFData), (downRecvStateCurr === DownRecvStateCRC ) -> Mux( downPendBuf.io.deq.fire & downPendBuf.io.deq.bits.tlast, DownRecvStateIdle, DownRecvStateCRC ), )) when( downRecvStateCurr =/= downRecvStateNext ){ downRecvCnt := 1.U } .elsewhen( downPendBuf.io.deq.fire ){ downRecvCnt := downRecvCnt + 1.U } //--------------- when( downRecvStateCurr === DownRecvStateOHead & downPendBuf.io.deq.fire ){ downOldHead := Cat( downOldHead.asUInt.tail(8), downPendBuf.io.deq.bits.tdata ).asTypeOf(new Header_Info_Bundle) } //--------------- val isDownNewHeadCreated = downRecvStateCurr === DownRecvStateSData & downRecvStateNext === DownRecvStateFData //新头是由老头产生,担忧会欠拍 when( isDownNewHeadCreated ){ downNewHead.length := Mux( downOldHead.length >= downLocalDataByte, downOldHead.length - downLocalDataByte, 0.U ) downNewHead.operator := downOldHead.operator downNewHead.param := downOldHead.param } when( downRecvStateCurr === DownRecvStateSData & downPendBuf.io.deq.fire ){ downRegTemp(downRecvCnt-1.U) := downPendBuf.io.deq.bits.tdata } //--------------- downForwardFifo.io.enq.valid := downRecvStateCurr === DownRecvStateFData & downPendBuf.io.deq.fire & ~isLastDevice downForwardFifo.io.enq.bits.tdata := downPendBuf.io.deq.bits.tdata downForwardFifo.io.enq.bits.tuser := downPendBuf.io.deq.bits.tuser downForwardFifo.io.enq.bits.tlast := downRecvCnt === (downForwardDataByte) | downPendBuf.io.deq.bits.tlast downPendBuf.io.deq.ready := (downRecvStateCurr === DownRecvStateOHead) | (downRecvStateCurr === DownRecvStateSData) | (downRecvStateCurr === DownRecvStateFData) | (downRecvStateCurr === DownRecvStateCRC ) when( downRecvStateCurr === DownRecvStateIdle & downRecvStateNext === DownRecvStateOHead){ isDownStreamError := false.B } .elsewhen( downForwardFifo.io.enq.fire & downForwardFifo.io.enq.bits.tuser ){ isDownStreamError := true.B printf("Warning, Wrong Package Received in DownStream, That could not happened!\n") } .elsewhen( downRecvStateCurr === DownRecvStateOHead & downRecvStateNext === DownRecvStateIdle ){ isDownStreamError := true.B printf("Warning, Wrong Package Received in DownStream, That could not happened!\n") } .elsewhen( downRecvStateCurr === DownRecvStateSData & downRecvStateNext === DownRecvStateIdle ){ isDownStreamError := true.B printf("Warning, Wrong Package Received in DownStream, That could not happened!\n") } .elsewhen( downRecvStateCurr === DownRecvStateFData & downRecvStateNext === DownRecvStateIdle ){ isDownStreamError := true.B printf("Warning, Wrong Package Received in DownStream, That could not happened!\n") } .elsewhen( downRecvStateCurr === DownRecvStateCRC & downPendBuf.io.deq.fire & downPendBuf.io.deq.bits.tlast & downRecvCnt =/= 4.U ){ isDownStreamError := true.B printf("Warning, Wrong Package Received in DownStream, That could not happened!\n") } .elsewhen( isDownNewHeadCreated & downOldHead.length < downLocalDataByte ){ //本包的负载不能满足本级数据需求,传输错误 isDownStreamError := true.B printf("Warning, Wrong Package Received in DownStream, That could not happened!\n") } .elsewhen( isDownNewHeadCreated & isLastDevice & downOldHead.length =/= downLocalDataByte ){ printf("Warning, Wrong Package Received in DownStream, SoftWare Check!\n") } assert( ~(downRecvStateCurr === DownRecvStateFData & ~downForwardFifo.io.enq.ready), "Assert Failed, downStream Forward Fifo is OverFlow!" ) } trait ShinSlvPhyDownStreamSend{ this: ShinSlvPhyBase => val DownSendStateIdle = 0.U val DownSendStateNHead = 1.U val DownSendStateFData = 2.U val downSendCnt = Reg(UInt(10.W)) val isDownNewHeadCreated: Bool val isLastDevice: Bool val downForwardDataByte: UInt val downNewHead: Header_Info_Bundle val downNewHeadShift: Header_Info_Bundle val isDownStreamError: Bool val downSendStateNext = Wire( UInt(3.W) ) val downSendStateCurr = RegNext( downSendStateNext, 0.U ) downSendStateNext := Mux1H(Seq( ( downSendStateCurr === DownSendStateIdle ) -> Mux( isDownNewHeadCreated & ~isLastDevice, DownSendStateNHead, DownSendStateIdle ), ( downSendStateCurr === DownSendStateNHead ) -> Mux( downSendCnt === ((headByte)).U & downStreamCdrOut.io.axis.fire, DownSendStateFData, DownSendStateNHead ), ( downSendStateCurr === DownSendStateFData ) -> Mux( downSendCnt === (downForwardDataByte ) & downStreamCdrOut.io.axis.fire, DownSendStateIdle, DownSendStateFData), )) when( downSendStateCurr =/= downSendStateNext ){ downSendCnt := 1.U } .elsewhen( downStreamCdrOut.io.axis.fire ){ downSendCnt := downSendCnt + 1.U } downStreamCdrOut.io.axis.valid := downSendStateCurr === DownSendStateNHead | downSendStateCurr === DownSendStateFData downStreamCdrOut.io.axis.bits.tdata := Mux1H(Seq( ( downSendStateCurr === DownSendStateNHead ) -> downNewHeadShift.asUInt(63,56), ( downSendStateCurr === DownSendStateFData ) -> downForwardFifo.io.deq.bits.tdata, )) val downOldHead: Header_Info_Bundle val downLocalDataByte: UInt when( isDownNewHeadCreated ){ downNewHeadShift.length := Mux( downOldHead.length >= downLocalDataByte, downOldHead.length - downLocalDataByte, 0.U ) downNewHeadShift.operator := downOldHead.operator downNewHeadShift.param := downOldHead.param } .elsewhen( downStreamCdrOut.io.axis.fire & downSendStateCurr === DownSendStateNHead ){ downNewHeadShift := (downNewHeadShift.asUInt << 8).asTypeOf(new Header_Info_Bundle) } downStreamCdrOut.io.axis.bits.tlast := ( downSendStateCurr === DownSendStateFData ) & downForwardFifo.io.deq.bits.tlast downStreamCdrOut.io.axis.bits.tuser := (( downSendStateCurr === DownSendStateFData ) & downForwardFifo.io.deq.bits.tuser ) | isDownStreamError downForwardFifo.io.deq.ready := downSendStateCurr === DownSendStateFData & downStreamCdrOut.io.axis.ready assert( ~(downStreamCdrIn.io.axis.valid & ~downStreamCdrIn.io.axis.ready) ) } abstract class ShinSlvPhyDownStream extends ShinSlvPhyBase with ShinSlvPhyDownStreamRecv with ShinSlvPhyDownStreamSend{ } trait ShinSlvPhyUpStreamRecv{ this: ShinSlvPhyDownStream => val UpRecvStateIdle = 0.U val UpRecvStateOHead = 1.U val UpRecvStateFData = 2.U val UpRecvStateCRC = 3.U val upOldHead = Reg( new Header_Info_Bundle ) val upNewHead = Reg( new Header_Info_Bundle ) val upPendBuf= Module( new Queue( new AXIS_Bundle(8), 2, pipe = true, flow = false ) with chisel3.util.experimental.InlineInstance) upStreamCdrIn.io.axis <> upPendBuf.io.enq val upRecvStateNext = Wire( UInt(3.W) ) val upRecvStateCurr = RegNext( upRecvStateNext, 0.U ) val upRecvCnt = Reg(UInt(10.W)) val isLastDevice: Bool upRecvStateNext := Mux1H(Seq( (upRecvStateCurr === UpRecvStateIdle ) -> Mux( upPendBuf.io.deq.valid, UpRecvStateOHead, UpRecvStateIdle ), (upRecvStateCurr === UpRecvStateOHead) -> Mux( upPendBuf.io.deq.fire, Mux( ~upPendBuf.io.deq.bits.tlast, Mux( upRecvCnt === ((headByte)).U, UpRecvStateFData, UpRecvStateOHead), UpRecvStateIdle), UpRecvStateOHead ), (upRecvStateCurr === UpRecvStateFData) -> Mux( upPendBuf.io.deq.fire, Mux( ~upPendBuf.io.deq.bits.tlast, Mux( upRecvCnt === (upOldHead.length), UpRecvStateCRC, UpRecvStateFData), UpRecvStateIdle), UpRecvStateFData ), (upRecvStateCurr === UpRecvStateCRC ) -> Mux( upPendBuf.io.deq.fire & upPendBuf.io.deq.bits.tlast, UpRecvStateIdle, UpRecvStateCRC ), )) when( upRecvStateCurr =/= upRecvStateNext){ upRecvCnt := 1.U } .elsewhen( upPendBuf.io.deq.fire ){ upRecvCnt := upRecvCnt + 1.U } val isLastDownStreamEnd = ( isLastDevice & (downRecvStateCurr === DownRecvStateCRC & downRecvStateNext === DownRecvStateIdle)) //--------------- when( (upRecvStateCurr === UpRecvStateOHead & upPendBuf.io.deq.fire) ){ upOldHead := Cat( upOldHead.asUInt.tail(8), upPendBuf.io.deq.bits.tdata ).asTypeOf(new Header_Info_Bundle) } .elsewhen( isLastDownStreamEnd ){ upOldHead.operator := downOldHead.operator upOldHead.length := 0.U upOldHead.param := downOldHead.param } //--------------- val upLocalDataByte = Mux1H(Seq( (upOldHead.operator === 0.U) -> OpInitByte.U, (upOldHead.operator === 1.U) -> OpBoardCastByte.U, (upOldHead.operator === 2.U) -> OpUniCastByte.U, )) val isUpNewHeadCreated = RegNext(upRecvStateCurr === UpRecvStateOHead & upRecvStateNext === UpRecvStateFData, false.B) | //补一拍 RegNext(isLastDownStreamEnd, false.B) when( isUpNewHeadCreated ){ upNewHead.length := upOldHead.length + upLocalDataByte upNewHead.operator := upOldHead.operator upNewHead.param := upOldHead.param } val upForwardDataByte = upOldHead.length //--------------- upForwardFifo.io.enq.valid := upRecvStateCurr === UpRecvStateFData & upPendBuf.io.deq.fire upForwardFifo.io.enq.bits.tdata := upPendBuf.io.deq.bits.tdata upForwardFifo.io.enq.bits.tuser := upPendBuf.io.deq.bits.tuser upForwardFifo.io.enq.bits.tlast := upRecvCnt === (upForwardDataByte) | upPendBuf.io.deq.bits.tlast upPendBuf.io.deq.ready := (upRecvStateCurr === UpRecvStateOHead) | ((upRecvStateCurr === UpRecvStateFData) & upForwardFifo.io.enq.ready) | (upRecvStateCurr === UpRecvStateCRC ) val isUpStreamError = RegInit( false.B ) when( (upRecvStateCurr === UpRecvStateIdle & upRecvStateNext === UpRecvStateOHead) | isLastDownStreamEnd ){ isUpStreamError := false.B } .elsewhen( upForwardFifo.io.enq.fire & upForwardFifo.io.enq.bits.tuser ){ isUpStreamError := true.B printf("Warning, Wrong Package Received in UpStream, That could not happened!\n") } .elsewhen( upRecvStateCurr === UpRecvStateOHead & upRecvStateNext === UpRecvStateIdle ){ isUpStreamError := true.B printf("Warning, Wrong Package Received in UpStream, That could not happened!\n") } .elsewhen( upRecvStateCurr === UpRecvStateFData & upRecvStateNext === UpRecvStateIdle ){ isUpStreamError := true.B printf("Warning, Wrong Package Received in UpStream, That could not happened!\n") } .elsewhen( upRecvStateCurr === UpRecvStateCRC & upPendBuf.io.deq.fire & upPendBuf.io.deq.bits.tlast & upRecvCnt =/= 4.U ){ isUpStreamError := true.B printf("Warning, Wrong Package Received in UpStream, That could not happened!\n") } assert( ~(upRecvStateCurr === UpRecvStateFData & ~upForwardFifo.io.enq.ready), "Assert Failed, upStream Forward Fifo is OverFlow!" ) } trait ShinSlvPhyUpStreamSend{ this: ShinSlvPhyDownStream => val UpSendStateIdle = 0.U val UpSendStateNHead = 1.U val UpSendStateLData = 2.U val UpSendStateFData = 3.U val upSendStateNext = Wire( UInt(3.W) ) val upSendStateCurr = RegNext( upSendStateNext, 0.U ) val upSendCnt = Reg(UInt(10.W)) val isUpNewHeadCreated: Bool val upLocalDataByte: UInt val isLastDevice: Bool val upForwardDataByte: UInt val upNewHead: Header_Info_Bundle val isUpStreamError: Bool upSendStateNext := Mux1H(Seq( ( upSendStateCurr === UpSendStateIdle ) -> Mux( isUpNewHeadCreated, UpSendStateNHead, UpSendStateIdle ), ( upSendStateCurr === UpSendStateNHead ) -> Mux( upSendCnt === ((headByte)).U & upStreamCdrOut.io.axis.fire, UpSendStateLData, UpSendStateNHead), ( upSendStateCurr === UpSendStateLData ) -> Mux( upSendCnt === (upLocalDataByte) & upStreamCdrOut.io.axis.fire, Mux( isLastDevice, UpSendStateIdle, UpSendStateFData), UpSendStateLData), ( upSendStateCurr === UpSendStateFData ) -> Mux( upSendCnt === (upForwardDataByte) & upStreamCdrOut.io.axis.fire, UpSendStateIdle, UpSendStateFData), )) when( upSendStateCurr =/= upSendStateNext ){ upSendCnt := 1.U } .elsewhen( upStreamCdrOut.io.axis.fire ){ upSendCnt := upSendCnt + 1.U } val upNewHeadShift = Reg(new Header_Info_Bundle) upStreamCdrOut.io.axis.valid := upSendStateCurr === UpSendStateNHead | upSendStateCurr === UpSendStateLData | upSendStateCurr === UpSendStateFData upStreamCdrOut.io.axis.bits.tdata := Mux1H(Seq( ( upSendStateCurr === UpSendStateNHead ) -> upNewHeadShift.asUInt(63,56), ( upSendStateCurr === UpSendStateLData ) -> upReg(upSendCnt-1.U), ( upSendStateCurr === UpSendStateFData ) -> upForwardFifo.io.deq.bits.tdata, )) val upOldHead: Header_Info_Bundle when( isUpNewHeadCreated ){ upNewHeadShift.length := upOldHead.length + upLocalDataByte upNewHeadShift.operator := upOldHead.operator upNewHeadShift.param := upOldHead.param } .elsewhen( upStreamCdrOut.io.axis.fire & upSendStateCurr === UpSendStateNHead ){ upNewHeadShift := (upNewHeadShift.asUInt << 8).asTypeOf(new Header_Info_Bundle) } upStreamCdrOut.io.axis.bits.tlast := ( upSendStateCurr === UpSendStateFData ) & upForwardFifo.io.deq.bits.tlast upStreamCdrOut.io.axis.bits.tuser := (( upSendStateCurr === UpSendStateFData ) & upForwardFifo.io.deq.bits.tuser ) | isUpStreamError upForwardFifo.io.deq.ready := upSendStateCurr === UpSendStateFData & upStreamCdrOut.io.axis.ready assert( ~(upStreamCdrIn.io.axis.valid & ~upStreamCdrIn.io.axis.ready) ) val isUpStreamEnd = (upSendStateCurr =/= UpSendStateIdle) & (upSendStateNext === UpSendStateIdle) } // trait ShinSlvPhyCloseLoop{ this: ShinSlvPhyDownStream => // val isLastDevice: Bool // } abstract class ShinSlvLinkBase extends ShinSlvPhyDownStream with ShinSlvPhyUpStreamRecv with ShinSlvPhyUpStreamSend // with ShinSlvPhyCloseLoop { } trait ShinSlvLinkInit{ this: ShinSlvLinkBase => //定义初始化任务 //下行定长包,各从机计算所在位置,更新ip地址寄存器,最后一个暂时通过IO实现闭环 //以下行包头解析时间,从机位置号,标定数据计算更新RTC时间寄存器 //上行根据包长,从站确定尾部伙伴数量(备用), //以上行包头解析时间放置本地时间 //更新末尾寄存器 //热拔出 可以通过 io自动闭环,通过返回包缩短识别 //热插入 必须带回寄存器信息,重新初始化,多发尾数据将被抛弃 //初始化应该下发 64*8 byte数据 对应 length = 512为slv0 504为slv1 ... val isInit = RegInit(false.B) val isLastInit = RegInit(false.B) val slvID = Reg(UInt(7.W)) val slvNum = Reg(UInt(7.W)) val slvRTC = Reg(UInt(64.W)) isLastDevice := isLastInit | io.isLast val isLegalInitDownHead = downOldHead.operator === 0.U & downOldHead.length(2,0) === "b000".U val isDownUpdate = RegInit(false.B) val isUpUpdate = RegInit(false.B) val isLastDownStreamEnd: Bool val isUpStreamEnd: Bool val upOldHead: Header_Info_Bundle val isUpNewHeadCreated: Bool when( (isDownNewHeadCreated | isLastDownStreamEnd) & isLegalInitDownHead ){ slvID := 64.U - (downOldHead.length >> 3) isDownUpdate := true.B } .elsewhen( isUpStreamEnd ){ isDownUpdate := false.B } when( (isDownNewHeadCreated | isLastDownStreamEnd) & isLegalInitDownHead ){ slvRTC := (64.U - (downOldHead.length >> 3)) << 5 // * 32 } .otherwise{ slvRTC := slvRTC + 1.U } when( isLastDownStreamEnd & isLegalInitDownHead ){ isLastInit := true.B } .elsewhen( isDownNewHeadCreated & isLegalInitDownHead ){ isLastInit := false.B } val isLegalInitUpHead = upOldHead.operator === 0.U & upOldHead.length(2,0) === "b000".U when( isUpNewHeadCreated ){ when( isLastDownStreamEnd ){ slvNum := 65.U - (downOldHead.length >> 3) isUpUpdate := true.B } .elsewhen(isLegalInitUpHead){ slvNum := (slvID + (upOldHead.length >> 3)) + 1.U isUpUpdate := true.B } } .elsewhen( isUpStreamEnd ){ isUpUpdate := false.B } when( isUpStreamEnd ){ isInit := ~isDownStreamError & ~isUpStreamError & isDownUpdate & isUpUpdate } val upRegMuxInit = isLegalInitUpHead when( upRegMuxInit ){ upReg(0) := slvRTC(7,0) upReg(1) := slvRTC(15,8) upReg(2) := slvRTC(23,16) upReg(3) := slvRTC(31,24) upReg(4) := slvRTC(39,32) upReg(5) := slvRTC(47,40) upReg(6) := slvRTC(55,48) upReg(7) := slvRTC(63,56) } } trait ShinSlvLinkBCast{ this: ShinSlvLinkBase => } trait ShinSlvLinkUCast{ this: ShinSlvLinkBase => } class ShinSlvBase extends ShinSlvLinkBase with ShinSlvLinkInit with ShinSlvLinkBCast with ShinSlvLinkUCast{ assert( VecInit(upRegMuxInit).count((x:Bool) => (x === true.B)) <= 1.U, "Assert Failed, upReg Collision Used!\n" ) val led = IO(UInt(8.W)) led := RegEnable( 1.U << slvID, 0.U, ~RegNext(isInit) & isInit) }