package BACK import chisel3._ import chisel3.util._ class FrameHeader extends Bundle{ val frameLenAim = UInt(12.W) //帧长度目标 val frameStyle = UInt(2.W) //包类型 } class SubMsgHeader extends Bundle{ val devIndex = UInt(14.W) // 子报文中设备索引 val style = UInt(2.W) // 子报文类型 val address = UInt(16.W) //子报文地址 val operator = UInt(4.W) //子报文命令类型 val length = UInt(12.W) //子报文负载长度 val workCnt = UInt(16.W) //子报文工作计数 } class ShareSRAMIO extends Bundle{ val addr = Input(UInt(15.W)) val dataw = Input( UInt(8.W) ) val datar = Output( UInt(8.W) ) val enw = Input(Bool()) val enr = Input(Bool()) } class SlaveParserIO extends Module{ val downIn = Flipped( Decoupled(new AXIS_Bundle(8)) ) val downOut = Decoupled(new AXIS_Bundle(8)) val upIn = Flipped( Decoupled(new AXIS_Bundle(8)) ) val upOut = Decoupled(new AXIS_Bundle(8)) val sram_r = for( 0 until 2 ) yield { Flipped(new ShareSRAMIO) } val sram_w = for( 0 until 2 ) yield { Flipped(new ShareSRAMIO) } } abstract class SlaveParserBase extends Module{ val io: SlaveParserIO = IO(new SlaveParserIO) val downRecParser = Module(new SlaveRecParser) val upRecParser = Module(new SlaveRecParser) val downSendGen = Module(new SlaveSendGen) val upSendGen = Module(new SlaveSendGen) val devIndex = Reg(UInt(14.W)) //当前设备索引 // 认为只有下行到下行,上行到上行模式,探针是独立发起操作 // val downSinkSel = Reg(Bool()) // val upSinkSel = Reg(Bool()) val downFrameInfo = Reg(new FrameHeader) val downSubMsgInfo = for( 0 until 2 ) yield { Reg(new SubMsgHeader) } val upFrameInfo = Reg(new FrameHeader) val upSubMsgInfo = for( 0 until 2 ) yield { Reg(new SubMsgHeader) } val isDownSendBusy = downRecParser.io.frameReq.ready val isUpSendBusy = upRecParser.io.frameReq.ready val isDownSendPend = RegInit(false.B) val isUpSendPend = RegInit(false.B) //处理主报文 //同时到来怎么办 when( downRecParser.io.frameReq.fire ){ when(downRecParser.io.frameReq.bits.frameStyle === FRAME_STYLE_PROBE){ //下行来了一个嗅探包 isUpSendPend := true.B downFrameInfo := downRecParser.io.frameReq.bits println("Warning! No busy protection!") } .elsewhen( downRecParser.io.frameReq.bits.frameStyle === FRAME_STYLE_COMMON ){ //下行来了一个普通包 isDownSendPend := true.B downFrameInfo := downRecParser.io.frameReq.bits println("Warning! No busy protection!") } } .elsewhen( upRecParser.io.frameReq.fire ){ when( upRecParser.io.frameReq.bits.frameStyle === FRAME_STYLE_PROBE){ //上行来了一个嗅探包 println("Probe Resp!") } .elsewhen( upRecParser.io.frameReq.bits.frameStyle === FRAME_STYLE_COMMON ){ //上行来了一个普通包 isUpSendPend := true.B upFrameInfo := upRecParser.io.frameReq.bits println("Warning! No busy protection!") } } val isDownSendProbe: Bool //下行探针 val isUpSendProbe: Bool //上行探针 val probeFrame: FrameHeader //固定化探针内容 downSendGen.io.frameReq.valid := isDownSendPend | isDownSendProbe //下行转发 | 下行探针 assert( OneHot(isDownSendPend, isDownSendProbe) ) downSendGen.io.frameReq.bits := Mux1H(Seq( isDownSendPend -> downFrameInfo, //下行转发 isDownSendProbe -> probeFrame, //下行探针 )) when( downSendGen.io.frameReq.fire ){ isDownSendPend := false.B } upSendGen.io.frameReq.valid := isUpSendPend | isUpSendProbe | //上行转发 | 上行探针 | 下行回环 assert( OneHot(isUpSendPend, isUpSendProbe) ) upSendGen.io.frameReq.bits := Mux1H(Seq( isUpSendPend -> upFrameInfo, //上行转发 isUpSendProbe -> probeFrame, //上行探针 , //下行回环 )) when( upSendGen.io.frameReq.fire ){ isUpSendPend := false.B } when( downSendGen.io.frameReq.fire ){ isDownSendPend := false.B } //子报文 val isDownSubMsgValid = for( i <- 0 until 2 ) yield { RegInit(false.B) } val isUpSubMsgValid = for( i <- 0 until 2 ) yield { RegInit(false.B) } //接收子报文 val downSubMsgInfo = for( i <- 0 until 2 ) yield { Reg(new SubMsgHeader) } val upSubMsgInfo = for( i <- 0 until 2 ) yield { Reg(new SubMsgHeader) } val downRecFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(8.W), 8)) } val upRecFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(8.W), 8)) } val isDownRecPing: Bool val isUpRecPing: Bool //下行接收 when( downRecParser.io.subMsgReq.fire ){ when( isDownRecPing ){ isDownSubMsgValid(0) := true.B downSubMsgInfo(0).devIndex := downRecParser.io.subMsgReq.bits.devIndex downSubMsgInfo(0).style := downRecParser.io.subMsgReq.bits.style downSubMsgInfo(0).address := downRecParser.io.subMsgReq.bits.address downSubMsgInfo(0).operator := downRecParser.io.subMsgReq.bits.operator downSubMsgInfo(0).length := downRecParser.io.subMsgReq.bits.length downSubMsgInfo(0).workCnt := downRecParser.io.subMsgReq.bits.workCnt downSubMsgInfo(0).source := 0.U //override 自身包 when( downRecParser.io.subMsgReq.bits.devIndex === localDevIndex ){ when( downRecParser.io.subMsgReq.bits.operator === 1.U ) {//写 sparser -》sram downSubMsgInfo(0).workCnt := downRecParser.io.subMsgReq.bits.workCnt + 1.U } .elsewhen( downRecParser.io.subMsgReq.bits.operator === 2.U ) {//读 ram ->fifo } .elsewhen( downRecParser.io.subMsgReq.bits.operator === 3.U ) {//读写 parser -》sram sram ->fifo downSubMsgInfo(0).workCnt := downRecParser.io.subMsgReq.bits.workCnt + 1.U } } } .otherwise{ isDownSubMsgValid(1) := true.B downSubMsgInfo(1).devIndex := downRecParser.io.subMsgReq.bits.devIndex downSubMsgInfo(1).style := downRecParser.io.subMsgReq.bits.style downSubMsgInfo(1).address := downRecParser.io.subMsgReq.bits.address downSubMsgInfo(1).operator := downRecParser.io.subMsgReq.bits.operator downSubMsgInfo(1).length := downRecParser.io.subMsgReq.bits.length downSubMsgInfo(1).workCnt := downRecParser.io.subMsgReq.bits.workCnt downSubMsgInfo(1).source := 1.U //override 自身包 when( downRecParser.io.subMsgReq.bits.devIndex === localDevIndex ){ when( downRecParser.io.subMsgReq.bits.operator === 1.U ) {//写 sparser -》sram downSubMsgInfo(1).workCnt := downRecParser.io.subMsgReq.bits.workCnt + 1.U } .elsewhen( downRecParser.io.subMsgReq.bits.operator === 2.U ) {//读 ram ->fifo } .elsewhen( downRecParser.io.subMsgReq.bits.operator === 3.U ) {//读写 parser -》sram sram ->fifo downSubMsgInfo(1).workCnt := downRecParser.io.subMsgReq.bits.workCnt + 1.U } } } } when( isDownRecPing ){ downRecFifo(0).io.enq.valid := downRecParser.io.data.valid downRecFifo(0).io.enq.bits := downRecParser.io.data.bits downRecParser.io.data.ready := downRecFifo(0).io.enq.ready } .otherwise{ downRecFifo(1).io.enq.valid := downRecParser.io.data.valid downRecFifo(1).io.enq.bits := downRecParser.io.data.bits downRecParser.io.data.ready := downRecFifo(1).io.enq.ready } //写入sram sram.io.enw := ( isDownRecPing & downSubMsgInfo(0).devIndex === localDevIndex & (downSubMsgInfo(0).operator === 1.U | downSubMsgInfo(0).operator === 3.U)) | (~isDownRecPing & downSubMsgInfo(1).devIndex === localDevIndex & (downSubMsgInfo(1).operator === 1.U | downSubMsgInfo(1).operator === 3.U)) sram.io.addrw := sram.io.dataw := downRecParser.io.data.bits //上行接收 when( upRecParser.io.subMsgReq.fire ){ when( isUpRecFifoPing ){ isUpSubMsgValid(0) := true.B upSubMsgInfo(0).devIndex := upRecParser.io.subMsgReq.bits.devIndex upSubMsgInfo(0).style := upRecParser.io.subMsgReq.bits.style upSubMsgInfo(0).address := upRecParser.io.subMsgReq.bits.address upSubMsgInfo(0).operator := upRecParser.io.subMsgReq.bits.operator upSubMsgInfo(0).length := upRecParser.io.subMsgReq.bits.length upSubMsgInfo(0).workCnt := upRecParser.io.subMsgReq.bits.workCnt upSubMsgInfo(0).source := 0.U //override 自身包 when( upRecParser.io.subMsgReq.bits.devIndex === localDevIndex ){ when( upRecParser.io.subMsgReq.bits.operator === 1.U ) {//写 sparser -》sram } .elsewhen( upRecParser.io.subMsgReq.bits.operator === 2.U ) {//读 ram ->fifo upSubMsgInfo(0).workCnt := upRecParser.io.subMsgReq.bits.workCnt + 1.U } .elsewhen( upRecParser.io.subMsgReq.bits.operator === 3.U ) {//读写 parser -》sram sram ->fifo upSubMsgInfo(0).workCnt := upRecParser.io.subMsgReq.bits.workCnt + 1.U } } } .otherwise{ isUpSubMsgValid(1) := true.B upSubMsgInfo(1).devIndex := upRecParser.io.subMsgReq.bits.devIndex upSubMsgInfo(1).style := upRecParser.io.subMsgReq.bits.style upSubMsgInfo(1).address := upRecParser.io.subMsgReq.bits.address upSubMsgInfo(1).operator := upRecParser.io.subMsgReq.bits.operator upSubMsgInfo(1).length := upRecParser.io.subMsgReq.bits.length upSubMsgInfo(1).workCnt := upRecParser.io.subMsgReq.bits.workCnt upSubMsgInfo(1).source := 1.U //override 自身包 when( upRecParser.io.subMsgReq.bits.devIndex === localDevIndex ){ when( upRecParser.io.subMsgReq.bits.operator === 1.U ) {//写 sparser -》sram } .elsewhen( upRecParser.io.subMsgReq.bits.operator === 2.U ) {//读 ram ->fifo upSubMsgInfo(1).workCnt := upRecParser.io.subMsgReq.bits.workCnt + 1.U } .elsewhen( upRecParser.io.subMsgReq.bits.operator === 3.U ) {//读写 parser -》sram sram ->fifo upSubMsgInfo(1).workCnt := upRecParser.io.subMsgReq.bits.workCnt + 1.U } } } } when( isUpRecFifoPing ){ upRecFifo(0).io.enq.valid := upRecParser.io.data.valid upRecFifo(0).io.enq.bits := Mux( upSubMsgInfo(0).devIndex === localDevIndex & (upSubMsgInfo(0).operator === 2.U | upSubMsgInfo(0).operator === 3.U), sram.io.datar, upRecParser.io.data.bits) upRecParser.io.data.ready := upRecFifo(0).io.enq.ready } .otherwise{ upRecFifo(1).io.enq.valid := upRecParser.io.data.valid upRecFifo(1).io.enq.bits := Mux( upSubMsgInfo(1).devIndex === localDevIndex & (upSubMsgInfo(1).operator === 2.U | upSubMsgInfo(1).operator === 3.U), sram.io.datar, upRecParser.io.data.bits) upRecParser.io.data.ready := upRecFifo(1).io.enq.ready } //读出SRAM sram.io.enr := ( isUpRecFifoPing & upSubMsgInfo(0).devIndex === localDevIndex & (upSubMsgInfo(0).operator === 1.U | upSubMsgInfo(0).operator === 3.U)) | (~isUpRecFifoPing & upSubMsgInfo(1).devIndex === localDevIndex & (upSubMsgInfo(1).operator === 1.U | upSubMsgInfo(1).operator === 3.U)) sram.io.addrr := //子报文下行发送 val isDownSendPing: Bool val isUpSendPing: Bool val isLastDevice: Bool downSendGen.io.subMsgReq.valid := ( isDownSendPing & isDownSubMsgValid(0) ) | (~isDownSendPing & isDownSubMsgValid(1)) downSendGen.io.subMsgReq.bits := Mux( isDownSendPing, downSubMsgInfo(0), downSubMsgInfo(1) ) when( downSendGen.io.subMsgReq.fire ){ //ready isDownSendPing := ~isDownSendPing when( isDownSendPing ){ isDownSubMsgValid(0) := false.B } .otherwise{ isDownSubMsgValid(1) := false.B } } downRecFifo(0).io.deq <> downSendGen.io.data(0) downRecFifo(1).io.deq <> downSendGen.io.data(1) //子报文上行发送 upSendGen.io.subMsgReq.valid := ( isUpSendPing & isUpSubMsgValid(0) ) | (~isUpSendPing & isUpSubMsgValid(1)) upSendGen.io.subMsgReq.bits := Mux( isUpSendPing, upSubMsgInfo(0), upSubMsgInfo(1) ) when( upSendGen.io.subMsgReq.fire ){ //ready isUpSendPing := ~isUpSendPing when( isUpSendPing ){ isUpSubMsgValid(0) := false.B } .otherwise{ isUpSubMsgValid(1) := false.B } } upRecFifo(0).io.deq <> upSendGen.io.data(0) upRecFifo(1).io.deq <> upSendGen.io.data(1) when(isLastDevice & downRecParser.io.stateCurr > ){ downSendGen.io.send <> upRecParser.io.rec } } class SlaveParser extends SlaveParserBase{ }