package BACK import chisel3._ import chisel3.util._ class TopBase_IO_Bundle extends Bundle{ val dDatIn = Input(Bool()) val dDatOut = Output(Bool()) val uDatIn = Input(Bool()) val uDatOut = Output(Bool()) val iqspi = new QSPIInterfaceIO val ospi = new SSPIInterfaceIO val oqspi = new QSPIInterfaceIO val iSync = Output(Vec(4, Bool())) val isSoftReset = Output(Bool()) val interrupt = Output(Bool()) val latchPin = Input(Vec(2, Bool())) val hwSerial = Input(UInt(48.W)) val uniCode = Input(UInt(64.W)) val pllCtrl = Output(UInt(32.W)) val xtal = Output(UInt(12.W)) val anamuxSel = Output(UInt(5.W)) val ldo2p5 = Output(UInt(8.W)) val ldo1p1 = Output(UInt(8.W)) val refTop = Output(UInt(3.W)) val bias = Output(UInt(2.W)) val spiSel = Output(UInt(2.W)) val isPllCfg = Output(Bool()) } class MstSlvSwitchIO extends TopBase_IO_Bundle{ val downCDROut = Flipped(new CDROutIO) val upCDROut = Flipped(new CDROutIO) val downCDRIn = Flipped(new CDRInIO) val upCDRIn = Flipped(new CDRInIO) } abstract class MstSlvSwitchBase extends Module with RequireAsyncReset{ val io: MstSlvSwitchIO = IO(new MstSlvSwitchIO) val slaveParser = Module(new SlaveParser ) val masterParser = Module(new MasterParser) val interface = Module(new Interface) interface.io.latchPin := io.latchPin interface.io.uniCode := io.uniCode interface.io.hwSerial := io.hwSerial interface.io.intTransEnd(0) := io.downCDRIn.axis.fire & io.downCDRIn.axis.bits.tlast interface.io.intTransEnd(1) := io.downCDROut.axis.fire & io.downCDROut.axis.bits.tlast interface.io.intTransEnd(2) := io.upCDRIn.axis.fire & io.upCDRIn.axis.bits.tlast interface.io.intTransEnd(3) := io.upCDROut.axis.fire & io.upCDROut.axis.bits.tlast io.isSoftReset := interface.io.isSoftReset io.interrupt := interface.io.interrupt io.ospi <> interface.io.ospi io.iqspi <> interface.io.iqspi io.oqspi <> interface.io.oqspi io.iSync := interface.io.sync io.pllCtrl := interface.io.cReg.pllCtrl io.xtal := interface.io.cReg.xtal io.anamuxSel := interface.io.cReg.anamuxSel io.ldo2p5 := interface.io.cReg.ldo2p5 io.ldo1p1 := interface.io.cReg.ldo1p1 io.refTop := interface.io.cReg.refTop io.bias := interface.io.cReg.bias io.spiSel := interface.io.cReg.spiSel io.isPllCfg := interface.io.isPllCfg val sram = Seq( for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) }, for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) }, for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) }, for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) }, for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) }, for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) }, for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) }, for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) }, ) val smUnit = Seq( Module( new SMUnit(depth = 4) ), Module( new SMUnit(depth = 4) ), Module( new SMUnit(depth = 4) ), Module( new SMUnit(depth = 4) ), Module( new SMUnit(depth = 2) ), Module( new SMUnit(depth = 2) ), Module( new SMUnit(depth = 2) ), Module( new SMUnit(depth = 2) ), ) val lvdsSMEnq = for( i <- 0 until 4 ) yield WireDefault(false.B); interface.io.lvdsSMEnq := lvdsSMEnq val lvdsSMDeq = for( i <- 0 until 4 ) yield WireDefault(false.B); interface.io.lvdsSMDeq := lvdsSMDeq smUnit(0).io.enq := lvdsSMEnq(0) smUnit(2).io.enq := lvdsSMEnq(1) smUnit(4).io.enq := lvdsSMEnq(2) smUnit(6).io.enq := lvdsSMEnq(3) smUnit(1).io.deq := lvdsSMDeq(0) smUnit(3).io.deq := lvdsSMDeq(1) smUnit(5).io.deq := lvdsSMDeq(2) smUnit(7).io.deq := lvdsSMDeq(3) smUnit(0).io.sram_r <> interface.io.sram_r(0) smUnit(2).io.sram_r <> interface.io.sram_r(1) smUnit(4).io.sram_r <> interface.io.sram_r(2) smUnit(6).io.sram_r <> interface.io.sram_r(3) smUnit(1).io.sram_w := interface.io.sram_w(0) smUnit(3).io.sram_w := interface.io.sram_w(1) smUnit(5).io.sram_w := interface.io.sram_w(2) smUnit(7).io.sram_w := interface.io.sram_w(3) smUnit(0).io.deq := interface.io.dSMdeq(0) smUnit(2).io.deq := interface.io.dSMdeq(1) smUnit(4).io.deq := interface.io.dSMdeq(2) smUnit(6).io.deq := interface.io.dSMdeq(3) smUnit(1).io.enq := interface.io.uSMenq(0) smUnit(3).io.enq := interface.io.uSMenq(1) smUnit(5).io.enq := interface.io.uSMenq(2) smUnit(7).io.enq := interface.io.uSMenq(3) for( i <- 0 until 8 ){ interface.io.smUsedDepth(i) := smUnit(i).io.cnt smUnit(i).io.flush := interface.io.isSMReset(i) } for( i <- 0 until 4 ){ for( j <- 0 until 4 ){ sram(i)(j).io.clockr := clock.asBool sram(i)(j).io.clockw := clock.asBool smUnit(i).io.sram(j).rd.datar := sram(i)(j).io.datar sram(i)(j).io.dataw := smUnit(i).io.sram(j).wr.dataw sram(i)(j).io.addrw := smUnit(i).io.sram(j).wr.addrw sram(i)(j).io.enw := smUnit(i).io.sram(j).wr.enw sram(i)(j).io.addrr := smUnit(i).io.sram(j).rd.addrr sram(i)(j).io.enr := smUnit(i).io.sram(j).rd.enr } } for( i <- 4 until 8 ){ for( j <- 0 until 2 ){ sram(i)(j).io.clockr := clock.asBool sram(i)(j).io.clockw := clock.asBool smUnit(i).io.sram(j).rd.datar := sram(i)(j).io.datar sram(i)(j).io.dataw := smUnit(i).io.sram(j).wr.dataw sram(i)(j).io.addrw := smUnit(i).io.sram(j).wr.addrw sram(i)(j).io.enw := smUnit(i).io.sram(j).wr.enw sram(i)(j).io.addrr := smUnit(i).io.sram(j).rd.addrr sram(i)(j).io.enr := smUnit(i).io.sram(j).rd.enr } } //default { smUnit(0).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO) smUnit(2).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO) smUnit(4).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO) smUnit(6).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO) smUnit(1).io.sram_r.enr := false.B smUnit(3).io.sram_r.enr := false.B smUnit(5).io.sram_r.enr := false.B smUnit(7).io.sram_r.enr := false.B smUnit(1).io.sram_r.addrr := 0.U smUnit(3).io.sram_r.addrr := 0.U smUnit(5).io.sram_r.addrr := 0.U smUnit(7).io.sram_r.addrr := 0.U slaveParser.io.sram_r(0).datar := 0.U slaveParser.io.sram_r(1).datar := 0.U slaveParser.io.sram_r(2).datar := 0.U slaveParser.io.sram_r(3).datar := 0.U masterParser.io.sram_r.datar := 0.U io.downCDRIn.axis.ready := false.B slaveParser.io.downIn.valid := false.B slaveParser.io.downIn.bits := 0.U.asTypeOf(new AXIS_Bundle(8)) slaveParser.io.downOut.ready := false.B masterParser.io.downOut.ready := false.B io.downCDROut.axis.valid := false.B io.downCDROut.axis.bits := 0.U.asTypeOf(new AXIS_Bundle(8)) io.upCDRIn.axis.ready := false.B slaveParser.io.upIn.valid := false.B slaveParser.io.upIn.bits := 0.U.asTypeOf(new AXIS_Bundle(8)) masterParser.io.upIn.valid := false.B masterParser.io.upIn.bits := 0.U.asTypeOf(new AXIS_Bundle(8)) slaveParser.io.upOut.ready := false.B io.upCDROut.axis.valid := false.B io.upCDROut.axis.bits := 0.U.asTypeOf(new AXIS_Bundle(8)) interface.io.mstDeltaTime := 0.U interface.io.slvDeltaTime := 0.U interface.io.deltaFinal := 0.U interface.io.intMstTrig(0) := false.B interface.io.intMstTrig(1) := false.B interface.io.intSlvTrig(0) := false.B interface.io.intSlvTrig(1) := false.B interface.io.intSlvTrig(2) := false.B interface.io.intSlvTrig(3) := false.B interface.io.intSlvTrig(4) := false.B interface.io.intSlvTrig(5) := false.B interface.io.intSlvTrig(6) := false.B interface.io.intSlvTrig(7) := false.B interface.io.intHWTrig(0) := false.B interface.io.intHWTrig(1) := false.B interface.io.downRecStat := 0.U.asTypeOf(new Stat_IO_Bundle) interface.io.upRecStat := 0.U.asTypeOf(new Stat_IO_Bundle) } } trait MstSlvSwitchMaster{ this: MstSlvSwitchBase => when( interface.io.cReg.modeSel === true.B ){ masterParser.io.downOut <> io.downCDROut.axis masterParser.io.upIn <> io.upCDRIn.axis } when( interface.io.cReg.modeSel === true.B ){ when( interface.io.txReq.bits.rxSM === 0.U ){ smUnit(0).io.sram_w := masterParser.io.sram_w lvdsSMEnq(0) := masterParser.io.rxEnq } .elsewhen( interface.io.txReq.bits.rxSM === 1.U ){ smUnit(2).io.sram_w := masterParser.io.sram_w lvdsSMEnq(1) := masterParser.io.rxEnq } .elsewhen( interface.io.txReq.bits.rxSM === 2.U ){ smUnit(4).io.sram_w := masterParser.io.sram_w lvdsSMEnq(2) := masterParser.io.rxEnq } .elsewhen( interface.io.txReq.bits.rxSM === 3.U ){ smUnit(6).io.sram_w := masterParser.io.sram_w lvdsSMEnq(3) := masterParser.io.rxEnq } when( interface.io.txReq.bits.txSM === 0.U ){ smUnit(1).io.sram_r <> masterParser.io.sram_r lvdsSMDeq(0) := masterParser.io.txDeq } .elsewhen( interface.io.txReq.bits.txSM === 1.U ){ smUnit(3).io.sram_r <> masterParser.io.sram_r lvdsSMDeq(1) := masterParser.io.txDeq } .elsewhen( interface.io.txReq.bits.txSM === 2.U ){ smUnit(5).io.sram_r <> masterParser.io.sram_r lvdsSMDeq(2) := masterParser.io.txDeq } .elsewhen( interface.io.txReq.bits.txSM === 3.U ){ smUnit(7).io.sram_r <> masterParser.io.sram_r lvdsSMDeq(3) := masterParser.io.txDeq } interface.io.mstDeltaTime := masterParser.io.deltaTimeStamp interface.io.intMstTrig(0) := masterParser.io.txDeq interface.io.intMstTrig(1) := masterParser.io.rxEnq interface.io.downRecStat := 0.U.asTypeOf(new Stat_IO_Bundle) interface.io.upRecStat := masterParser.io.upRecStat } masterParser.io.req := interface.io.txReq.valid // masterParser.io.req.bits.txLength := interface.io.txReq.bits.txLength // io.rsp := masterParser.io.rsp masterParser.io.cReg := interface.io.cReg masterParser.io.mReg := interface.io.mReg } trait MstSlvSwitchSlave{ this: MstSlvSwitchBase => when( interface.io.cReg.modeSel === false.B ){ slaveParser.io.downIn <> io.downCDRIn.axis io.downCDROut.axis <> slaveParser.io.downOut slaveParser.io.upIn <> io.upCDRIn.axis io.upCDROut.axis <> slaveParser.io.upOut } slaveParser.io.cReg := interface.io.cReg slaveParser.io.sReg := interface.io.sReg when( interface.io.cReg.modeSel === false.B ){ smUnit(0).io.sram_w := slaveParser.io.sram_w(0) smUnit(2).io.sram_w := slaveParser.io.sram_w(1) smUnit(4).io.sram_w := slaveParser.io.sram_w(2) smUnit(6).io.sram_w := slaveParser.io.sram_w(3) smUnit(1).io.sram_r <> slaveParser.io.sram_r(0) smUnit(3).io.sram_r <> slaveParser.io.sram_r(1) smUnit(5).io.sram_r <> slaveParser.io.sram_r(2) smUnit(7).io.sram_r <> slaveParser.io.sram_r(3) lvdsSMEnq(0) := slaveParser.io.dSMenq(0) lvdsSMEnq(1) := slaveParser.io.dSMenq(1) lvdsSMEnq(2) := slaveParser.io.dSMenq(2) lvdsSMEnq(3) := slaveParser.io.dSMenq(3) lvdsSMDeq(0) := slaveParser.io.uSMdeq(0) lvdsSMDeq(1) := slaveParser.io.uSMdeq(1) lvdsSMDeq(2) := slaveParser.io.uSMdeq(2) lvdsSMDeq(3) := slaveParser.io.uSMdeq(3) interface.io.mstDeltaTime := slaveParser.io.mstDeltaTimeStamp interface.io.slvDeltaTime := slaveParser.io.slvDeltaTime interface.io.deltaFinal := slaveParser.io.deltaFinal interface.io.intSlvTrig(0) := slaveParser.io.dSMenq(0) interface.io.intSlvTrig(1) := slaveParser.io.uSMdeq(0) interface.io.intSlvTrig(2) := slaveParser.io.dSMenq(1) interface.io.intSlvTrig(3) := slaveParser.io.uSMdeq(1) interface.io.intSlvTrig(4) := slaveParser.io.dSMenq(2) interface.io.intSlvTrig(5) := slaveParser.io.uSMdeq(2) interface.io.intSlvTrig(6) := slaveParser.io.dSMenq(3) interface.io.intSlvTrig(7) := slaveParser.io.uSMdeq(3) interface.io.intHWTrig(0) := slaveParser.io.intHWTrig(0) interface.io.intHWTrig(1) := slaveParser.io.intHWTrig(1) interface.io.downRecStat := slaveParser.io.downRecStat interface.io.upRecStat := slaveParser.io.upRecStat } slaveParser.io.intHWClr(0) := interface.io.intHWTrig(0) & interface.io.intHWClr(0) slaveParser.io.intHWClr(1) := interface.io.intHWTrig(1) & interface.io.intHWClr(1) io.downCDRIn.flush := RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) ) io.upCDRIn.flush := RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) ) io.downCDROut.flush := RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) ) io.upCDROut.flush := RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) ) interface.io.lvds <> slaveParser.io.lvds interface.io.localDevIndex := slaveParser.io.localDevIndex //从站链路寄存器 // interface.io.isDevOnLeft := slaveParser.io.isDevOnLeft // interface.io.isDevOnLeftModify := slaveParser.io.isDevOnLeftModify // interface.io.indexOfLeftDev := slaveParser.io.indexOfLeftDev interface.io.isDevOnRight := slaveParser.io.isDevOnRight interface.io.isDevOnRightModify := slaveParser.io.isDevOnRightModify interface.io.indexOfRightDev := slaveParser.io.indexOfRightDev } trait MstSlvSwitchWatchDog{ this: MstSlvSwitchBase => //看门狗1~16,SM监控 val isWdtSMEnable = for( _ <- 0 until 16 ) yield { RegInit(false.B) } val wdtSMCnt = for( _ <- 0 until 16 ) yield { Reg(UInt(32.W)) } for( i <- 0 until 8 ){ when( smUnit(i).io.enq ){ isWdtSMEnable(2*i) := false.B } .elsewhen( ~isWdtSMEnable(2*i) & smUnit(i).io.sram_w.enw & interface.io.cReg.wdtEnable.extract(i+1) ){ isWdtSMEnable(2*i) := true.B } when( smUnit(i).io.deq ){ isWdtSMEnable(2*i + 1) := false.B } .elsewhen( ~isWdtSMEnable(2*i + 1) & smUnit(i).io.sram_r.enr & interface.io.cReg.wdtEnable.extract(i+1) ){ isWdtSMEnable(2*i + 1) := true.B } } for( i <- 0 until 16 ){ when( isWdtSMEnable(i) & (wdtSMCnt(i) < interface.io.cReg.wdtTarCnt(i+1)) ){ wdtSMCnt(i) := wdtSMCnt(i) + 1.U } .elsewhen( ~isWdtSMEnable(i) || (wdtSMCnt(i) >= interface.io.cReg.wdtTarCnt(i+1)) ){ wdtSMCnt(i) := 0.U } // assert( wdtSMCnt(i) <= interface.io.cReg.wdtTarCnt(i+1), s"Assert Failed! wdtSMCnt($i) is larger than wdtTarCnt, Special situation?" ) interface.io.wdtTrigger(i+1) := wdtSMCnt(i) === interface.io.cReg.wdtTarCnt(i+1) } //看门狗0 发送后回包是否超时 val isWdtRec2RtnEnable = RegInit(false.B) val wdtRec2RtnCnt = Reg(UInt(32.W)) when( (io.upCDRIn.axis.fire & io.upCDRIn.axis.bits.tlast) | ~interface.io.cReg.wdtEnable.extract(0) ){ isWdtRec2RtnEnable := false.B } .elsewhen( ~isWdtRec2RtnEnable & io.downCDROut.axis.fire & interface.io.cReg.wdtEnable.extract(0) ){ isWdtRec2RtnEnable := true.B } when( isWdtRec2RtnEnable & (wdtRec2RtnCnt < interface.io.cReg.wdtTarCnt(0)) ){ wdtRec2RtnCnt := wdtRec2RtnCnt + 1.U } .elsewhen( ~isWdtRec2RtnEnable || (wdtRec2RtnCnt >= interface.io.cReg.wdtTarCnt(0)) ){ wdtRec2RtnCnt := 0.U } // assert( wdtRecCnt < interface.io.cReg.wdtTarCnt(0), "Assert Failed! wdtRecCnt is larger than wdtTarCnt, Special situation?" ) interface.io.wdtTrigger(0) := wdtRec2RtnCnt === interface.io.cReg.wdtTarCnt(0) //看门狗17 val wdtRec2RecCnt = Reg(UInt(32.W)) when( interface.io.cReg.wdtEnable.extract(17) & (wdtRec2RecCnt < interface.io.cReg.wdtTarCnt(17)) ){ wdtRec2RecCnt := wdtRec2RecCnt + 1.U } .elsewhen( ~interface.io.cReg.wdtEnable.extract(17) || io.downCDRIn.axis.fire || (wdtRec2RecCnt >= interface.io.cReg.wdtTarCnt(17)) ){ wdtRec2RecCnt := 0.U } interface.io.wdtTrigger(17) := wdtRec2RecCnt === interface.io.cReg.wdtTarCnt(17) } class MstSlvSwitch extends MstSlvSwitchBase with MstSlvSwitchMaster with MstSlvSwitchSlave with MstSlvSwitchWatchDog{ val isDwUpEx = interface.io.cReg.dwupEx(15,8) === "h58".U && interface.io.cReg.dwupEx.extract(0) when( ~isDwUpEx ){ //未交叉 when( interface.io.cReg.modeSel === false.B ){ //slave when( (slaveParser.io.intHWTrig(0) | slaveParser.io.intHWTrig(1)) | interface.io.isPoReset ){ //硬件错误 io.downCDRIn.serDat := false.B io.upCDRIn.serDat := false.B when( slaveParser.io.isLoop ){ //回环 io.dDatOut := false.B io.uDatOut := io.dDatIn } .otherwise{ //非回环 io.dDatOut := io.dDatIn io.uDatOut := io.uDatIn } } .otherwise{ //无硬件错误 when( slaveParser.io.isLoop ){ //回环 io.downCDRIn.serDat := io.dDatIn io.upCDRIn.serDat := io.downCDROut.serDat io.dDatOut := false.B io.uDatOut := io.upCDROut.serDat } .otherwise{ //非回环 io.downCDRIn.serDat := io.dDatIn io.upCDRIn.serDat := io.uDatIn io.dDatOut := io.downCDROut.serDat io.uDatOut := io.upCDROut.serDat } } } .otherwise{ //master io.downCDRIn.serDat := false.B io.upCDRIn.serDat := io.uDatIn io.dDatOut := io.downCDROut.serDat io.uDatOut := false.B } } .otherwise{ //交叉 when( interface.io.cReg.modeSel === false.B ){ //slave when( (slaveParser.io.intHWTrig(0) | slaveParser.io.intHWTrig(1)) | interface.io.isPoReset ){ //硬件错误 when( slaveParser.io.isLoop ){ //回环 io.dDatOut := io.uDatIn io.uDatOut := false.B io.downCDRIn.serDat := false.B io.upCDRIn.serDat := false.B } .otherwise{ //非回环 io.dDatOut := io.dDatIn io.uDatOut := io.uDatIn io.downCDRIn.serDat := false.B io.upCDRIn.serDat := false.B } } .otherwise{ //无硬件错误 when( slaveParser.io.isLoop ){ //回环 io.downCDRIn.serDat := io.uDatIn io.upCDRIn.serDat := io.downCDROut.serDat io.uDatOut := false.B io.dDatOut := io.upCDROut.serDat } .otherwise{ //非回环 io.downCDRIn.serDat := io.uDatIn io.upCDRIn.serDat := io.dDatIn io.dDatOut := io.upCDROut.serDat io.uDatOut := io.downCDROut.serDat } } } .otherwise{ //master io.downCDRIn.serDat := false.B io.upCDRIn.serDat := io.dDatIn io.uDatOut := io.downCDROut.serDat io.dDatOut := false.B } } }