package BACK import chisel3._ import chisel3.util._ class SlaveRecParserIO extends Bundle{ val rec = Flipped( Decoupled(new AXIS_Bundle(8)) ) val data = Decoupled(UInt(8.W)) val stateNext = Output(UInt(4.W)) val stateCurr = Output(UInt(4.W)) val frameReq = Valid( new FrameHeader ) val subMsgReq = Valid( new SubMsgHeader ) val resp = Input(Bool()) val isError = Output(Bool()) } class SlaveRecParser extends Module{ val io: SlaveRecParserIO = IO(new SlaveRecParserIO) val crc = Module(new crc32_8) val STATE_IDLE = 0.U //空闲 val STATE_HEADER = 1.U //长度/ /保留2bits //包类型 val STATE_SUBMSG_HEADER = 2.U //子报文设备索引 //子报文类型 val STATE_PAYLOAD_DATA = 3.U //子报文数据 val STATE_CRC = 4.U //CRC校验 val STATE_ERROR = 5.U // val STATE_WAIT = 6.U val stateNext = Wire(UInt(4.W)); io.stateNext := stateNext val stateCurr = RegNext(stateNext, STATE_IDLE); io.stateCurr := stateCurr io.isError := stateCurr === STATE_ERROR io.rec.ready := stateCurr =/= STATE_IDLE crc.io.isEnable := io.rec.fire & ( stateCurr === STATE_HEADER | stateCurr === STATE_SUBMSG_HEADER | stateCurr === STATE_PAYLOAD_DATA ) crc.io.dataIn := io.rec.bits.tdata crc.reset := reset.asBool | stateCurr === STATE_IDLE val crcData = Reg(UInt(32.W)) val isCrcPass = crc.io.crc === Cat( crcData(23,0), io.rec.bits.tdata ) when( io.rec.fire & stateCurr === STATE_CRC ){ crcData := Cat( crcData(23,0), io.rec.bits.tdata ) } val FRAME_STYLE_COMMON = 0.U val FRAME_STYLE_PROBE = 1.U val lengthCnt = RegInit(0.U(12.W)) //动态计数器 val frameLenCnt = Reg(UInt(12.W)) //帧长度计数 io.frameReq.valid := io.rec.fire & (stateCurr === STATE_HEADER) & (stateNext =/= STATE_HEADER) val frameHeader = Reg(new FrameHeader) io.frameReq.bits.frameLenAim := frameHeader.frameLenAim io.frameReq.bits.frameStyle := frameHeader.frameStyle io.frameReq.bits.frameInfo := frameHeader.frameInfo | io.rec.bits.tdata io.subMsgReq.valid := io.rec.fire & (stateCurr === STATE_SUBMSG_HEADER) & (stateNext === STATE_PAYLOAD_DATA) val subMsgHeader = Reg(new SubMsgHeader) io.subMsgReq.bits.devIndex := subMsgHeader.devIndex io.subMsgReq.bits.style := subMsgHeader.style io.subMsgReq.bits.address := subMsgHeader.address io.subMsgReq.bits.operator := subMsgHeader.operator io.subMsgReq.bits.length := subMsgHeader.length io.subMsgReq.bits.workCnt := subMsgHeader.workCnt | io.rec.bits.tdata(7,0) when( io.rec.fire ){ when( stateCurr =/= stateNext ){ lengthCnt := 0.U } .otherwise{ lengthCnt := lengthCnt + 1.U } } when( io.rec.fire ){ when( stateCurr === STATE_HEADER ){ frameLenCnt := 0.U } .elsewhen( ( stateCurr === STATE_SUBMSG_HEADER ) || ( stateCurr === STATE_PAYLOAD_DATA ) ){ frameLenCnt := frameLenCnt + 1.U } } io.data.valid := io.rec.fire & stateCurr === STATE_PAYLOAD_DATA io.data.bits := io.rec.bits.tdata assert( ~(io.data.valid & ~io.data.ready), "Assert Failed! Receive Data was rejected by fifo!" ) when( io.rec.fire ){ when( stateCurr === STATE_HEADER & lengthCnt === 0.U ){ frameHeader.frameLenAim := io.rec.bits.tdata << 4 } .elsewhen( stateCurr === STATE_HEADER & lengthCnt === 1.U ){ frameHeader.frameLenAim := frameHeader.frameLenAim | io.rec.bits.tdata(7,4) frameHeader.frameStyle := io.rec.bits.tdata(1,0) } .elsewhen( stateCurr === STATE_HEADER & lengthCnt === 2.U ){ frameHeader.frameInfo := io.rec.bits.tdata << 8 } .elsewhen( stateCurr === STATE_HEADER & lengthCnt === 3.U ){ frameHeader.frameInfo := frameHeader.frameInfo | io.rec.bits.tdata } when( stateCurr === STATE_SUBMSG_HEADER & lengthCnt === 0.U ){ subMsgHeader.devIndex := io.rec.bits.tdata << 6 } .elsewhen( stateCurr === STATE_SUBMSG_HEADER & lengthCnt === 1.U ){ subMsgHeader.devIndex := subMsgHeader.devIndex | io.rec.bits.tdata(7,2) subMsgHeader.style := io.rec.bits.tdata(1,0) } .elsewhen( stateCurr === STATE_SUBMSG_HEADER & lengthCnt === 2.U ){ subMsgHeader.address := io.rec.bits.tdata << 8 } .elsewhen( stateCurr === STATE_SUBMSG_HEADER & lengthCnt === 3.U ){ subMsgHeader.address := subMsgHeader.address | io.rec.bits.tdata } .elsewhen( stateCurr === STATE_SUBMSG_HEADER & lengthCnt === 4.U ){ subMsgHeader.operator := io.rec.bits.tdata(7,4) subMsgHeader.length := io.rec.bits.tdata(3,0) << 8 } .elsewhen( stateCurr === STATE_SUBMSG_HEADER & lengthCnt === 5.U ){ subMsgHeader.length := subMsgHeader.length | io.rec.bits.tdata(7,0) } .elsewhen( stateCurr === STATE_SUBMSG_HEADER & lengthCnt === 6.U ){ subMsgHeader.workCnt := io.rec.bits.tdata(7,0) << 8 } .elsewhen( stateCurr === STATE_SUBMSG_HEADER & lengthCnt === 7.U ){ subMsgHeader.workCnt := subMsgHeader.workCnt | io.rec.bits.tdata(7,0) } } stateNext := Mux1H(Seq( //必须使用上升沿触发,以避免前一帧长度超过预期 ( stateCurr === STATE_IDLE ) -> Mux( ~RegNext(io.rec.valid) & io.rec.valid, STATE_HEADER, STATE_IDLE ), ( stateCurr === STATE_HEADER ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast, STATE_ERROR, Mux( lengthCnt === (4-1).U, MuxCase( STATE_ERROR, Array( ( frameHeader.frameStyle === FRAME_STYLE_COMMON ) -> STATE_SUBMSG_HEADER, ( frameHeader.frameStyle === FRAME_STYLE_PROBE ) -> STATE_CRC, )), STATE_HEADER )), STATE_HEADER ), ( stateCurr === STATE_SUBMSG_HEADER ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast, STATE_ERROR, Mux( lengthCnt === (8-1).U, STATE_PAYLOAD_DATA, STATE_SUBMSG_HEADER ) ), STATE_SUBMSG_HEADER), ( stateCurr === STATE_PAYLOAD_DATA ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast, STATE_ERROR, Mux( lengthCnt === ( subMsgHeader.length - 1.U), Mux( frameLenCnt === frameHeader.frameLenAim - 1.U, STATE_CRC, STATE_SUBMSG_HEADER ), STATE_PAYLOAD_DATA ) ), STATE_PAYLOAD_DATA), ( stateCurr === STATE_CRC ) -> Mux( io.rec.fire & io.rec.bits.tlast, Mux( lengthCnt === (4 - 1).U & isCrcPass, STATE_IDLE, STATE_ERROR ), STATE_CRC ), ( stateCurr === STATE_ERROR ) -> Mux( io.resp, STATE_IDLE, STATE_ERROR ), ( stateCurr === STATE_WAIT ) -> Mux( io.resp, STATE_IDLE, STATE_WAIT ) )) }