package BACK import chisel3._ import chisel3.util._ class SubMsgTxInfo extends SubMsgHeader{ val source = UInt(2.W) } class SlaveSendGenIO extends Bundle{ val data = Vec(2, Flipped( Decoupled(UInt(8.W)) ) ) val frameReq = Flipped(Decoupled( new FrameHeader )) val subMsgReq = Flipped(Decoupled( new SubMsgTxInfo )) val send = Decoupled(new AXIS_Bundle(8)) val isError = Output(Bool()) } class SlaveSendGen extends Module{ val io: SlaveSendGenIO = IO(new SlaveSendGenIO) val crc = Module(new crc32_8) val FRAME_STYLE_COMMON = 0.U val FRAME_STYLE_PROBE = 1.U val STATE_IDLE = 0.U //空闲 val STATE_FRAME_HEADER = 1.U //长度/ /保留2bits //包类型 val STATE_SUBMSG_HEADER = 2.U val STATE_SUBMSG_DATA = 3.U val STATE_CRC = 4.U //CRC校验 val STATE_ERROR = 5.U // val STATE_WAIT = 6.U val stateNext = Wire(UInt(3.W)) val stateCurr = RegNext(stateNext, STATE_IDLE) io.isError := stateCurr === STATE_ERROR crc.io.isEnable := io.send.fire & ( stateCurr === STATE_FRAME_HEADER | stateCurr === STATE_SUBMSG_HEADER | stateCurr === STATE_SUBMSG_DATA ) crc.reset := reset.asBool | stateCurr === STATE_IDLE val frameInfo = Reg(new FrameHeader) val subMsgInfo = for( _ <- 0 until 2 ) yield { Reg(new SubMsgTxInfo) } val isPingFill = RegInit(false.B) val isPingEmit = RegInit(false.B) when( io.frameReq.fire ){ frameInfo := io.frameReq.bits } when( io.subMsgReq.fire ){ when( isPingFill ){ subMsgInfo(0) := io.subMsgReq.bits } .otherwise{ subMsgInfo(1) := io.subMsgReq.bits } } val lengthCnt = Reg(UInt(12.W)) val frameLenCnt = Reg(UInt(12.W)) when( io.send.fire ){ when( stateCurr === STATE_FRAME_HEADER ){ frameLenCnt := 0.U } .elsewhen( stateCurr === STATE_SUBMSG_HEADER || stateCurr === STATE_SUBMSG_DATA ){ frameLenCnt := frameLenCnt + 1.U } } when( stateCurr =/= stateNext ){ lengthCnt := 0.U } .elsewhen(io.send.fire){ lengthCnt := lengthCnt + 1.U } val subMsgInfoSel = Mux( isPingEmit, subMsgInfo(0), subMsgInfo(1) ) io.frameReq.ready := true.B io.subMsgReq.ready := stateCurr =/= STATE_SUBMSG_HEADER & stateNext === STATE_SUBMSG_HEADER stateNext := Mux1H(Seq( (stateCurr === STATE_IDLE) -> Mux( io.frameReq.fire, STATE_FRAME_HEADER, STATE_IDLE ), (stateCurr === STATE_FRAME_HEADER) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, Mux( frameInfo.frameStyle === FRAME_STYLE_COMMON, Mux(io.subMsgReq.valid, STATE_SUBMSG_HEADER, STATE_ERROR), STATE_CRC ), STATE_FRAME_HEADER), STATE_FRAME_HEADER ), (stateCurr === STATE_SUBMSG_HEADER) -> Mux( io.send.fire, Mux( lengthCnt === (8-1).U, STATE_SUBMSG_DATA, STATE_SUBMSG_HEADER), STATE_SUBMSG_HEADER), (stateCurr === STATE_SUBMSG_DATA) -> Mux( io.send.fire, Mux( lengthCnt === subMsgInfoSel.length-1.U, //已经发送完成该子报文 Mux( frameLenCnt === frameInfo.frameLenAim -1.U, STATE_CRC, //主报文长度达到, 进CRC Mux( io.subMsgReq.valid, STATE_SUBMSG_HEADER, STATE_ERROR ) ), //主报文长度未到,进下一个子报文 STATE_SUBMSG_DATA ), STATE_SUBMSG_DATA ), (stateCurr === STATE_CRC) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, STATE_IDLE, STATE_CRC ), STATE_CRC), (stateCurr === STATE_ERROR) -> Mux( io.send.fire, STATE_IDLE, STATE_ERROR), )) io.data(0).ready := io.send.fire & (stateCurr === STATE_SUBMSG_DATA) & (subMsgInfoSel.source === 0.U) io.data(1).ready := io.send.fire & (stateCurr === STATE_SUBMSG_DATA) & (subMsgInfoSel.source === 1.U) assert( ~(io.data(0).ready & ~io.data(0).valid) ) assert( ~(io.data(1).ready & ~io.data(1).valid) ) io.send.valid := (stateCurr === STATE_FRAME_HEADER) | (stateCurr === STATE_SUBMSG_HEADER) | (stateCurr === STATE_SUBMSG_DATA & ( (io.data(0).valid & subMsgInfoSel.source === 0.U) | (io.data(1).valid & subMsgInfoSel.source === 1.U) )) | (stateCurr === STATE_CRC) val tdata_frame_header = Mux1H(Seq( (lengthCnt === 0.U) -> frameInfo.frameLenAim(11,4), (lengthCnt === 1.U) -> Cat( frameInfo.frameLenAim(3,0), 0.U(2.W), frameInfo.frameStyle), (lengthCnt === 2.U) -> frameInfo.frameInfo(15,8), (lengthCnt === 3.U) -> frameInfo.frameInfo( 7,0), )) val tdata_submsg_header = Mux1H(Seq( (lengthCnt === 0.U) -> subMsgInfoSel.devIndex(13,6), (lengthCnt === 1.U) -> Cat( subMsgInfoSel.devIndex(5,0), subMsgInfoSel.style), (lengthCnt === 2.U) -> subMsgInfoSel.address(15,8), (lengthCnt === 3.U) -> subMsgInfoSel.address(7,0), (lengthCnt === 4.U) -> Cat(subMsgInfoSel.operator, subMsgInfoSel.length(11,8)), (lengthCnt === 5.U) -> subMsgInfoSel.length(7,0), (lengthCnt === 6.U) -> subMsgInfoSel.workCnt(15,8), (lengthCnt === 7.U) -> subMsgInfoSel.workCnt(7,0), )) val tdata_submsg_data = Mux1H(Seq( (subMsgInfoSel.source === 0.U) -> io.data(0).bits, (subMsgInfoSel.source === 1.U) -> io.data(1).bits, )) crc.io.dataIn := Mux1H(Seq( (stateCurr === STATE_FRAME_HEADER) -> tdata_frame_header, (stateCurr === STATE_SUBMSG_HEADER) -> tdata_submsg_header, (stateCurr === STATE_SUBMSG_DATA) -> tdata_submsg_data, )) val tdata_crc = Mux1H(Seq( (lengthCnt === 0.U) -> crc.io.crc(31,24), (lengthCnt === 1.U) -> crc.io.crc(23,16), (lengthCnt === 2.U) -> crc.io.crc(15, 8), (lengthCnt === 3.U) -> crc.io.crc( 7, 0), )) io.send.bits.tdata := Mux1H(Seq( (stateCurr === STATE_FRAME_HEADER) -> tdata_frame_header, (stateCurr === STATE_SUBMSG_HEADER) -> tdata_submsg_header, (stateCurr === STATE_SUBMSG_DATA) -> tdata_submsg_data, (stateCurr === STATE_CRC) -> tdata_crc, )) io.send.bits.tuser := (stateCurr === STATE_ERROR & stateNext === STATE_IDLE) io.send.bits.tlast := (stateCurr === STATE_CRC & stateNext === STATE_IDLE) || (stateCurr === STATE_ERROR & stateNext === STATE_IDLE) }