package BACK import chisel3._ import chisel3.util._ class FSMC_Port_Bundle extends Bundle{ val addr = Input(UInt(13.W)) val dataIn = Input(UInt(8.W)) val dataOut = Output(UInt(8.W)) val dataOEn = Output(Bool()) val cen = Input(Bool()) val oen = Input(Bool()) val wen = Input(Bool()) } class BackBoardMstIO extends Bundle{ val FSMC = new FSMC_Port_Bundle val reset = Input(Bool()) val oser_pclk = Input(Bool()) val oser_fclk = Input(Bool()) val ides_pclk = Input(Bool()) val ides_fclk = Input(Bool()) val lvds_down_dout = Output(Bool()) val lvds_up_din = Input(Bool()) } class BackBoardMstBase extends RawModule{ val io: BackBoardMstIO = IO(new BackBoardMstIO) val lvdsMst = Module(new Lvds_Bus_Master) val mirrorDown = Module(new MirrorSRAM(8, 2048)) val mirrorUp = Module(new MirrorSRAM(8, 2048)) val status = Wire(UInt(8.W)) val slvNum = Wire(UInt(5.W)) mirrorDown.io.clock := io.ides_pclk.asBool mirrorDown.io.reset := io.reset.asBool mirrorUp.io.clock := io.ides_pclk.asBool mirrorUp.io.reset := io.reset.asBool } trait BackBoardMstFSMC{ this: BackBoardMstBase => withClockAndReset( io.ides_pclk.asClock, io.reset ){ val statusReg = RegInit(0.U(8.W)); status := statusReg val slvNumReg = RegInit(0.U(5.W)); slvNum := slvNumReg val fsmcAddrSync = ShiftRegister( io.FSMC.addr, 2, 0.U, true.B ) val fsmcdataInSync = ShiftRegister( io.FSMC.dataIn, 2, 0.U, true.B ) val fsmcCEnSync = ShiftRegister( io.FSMC.cen, 2, true.B, true.B ) val fsmcOEnSync = ShiftRegister( io.FSMC.oen, 2, true.B, true.B ) val fsmcWEnSync = ShiftRegister( io.FSMC.wen, 2, true.B, true.B ) io.FSMC.dataOEn := io.FSMC.oen mirrorDown.io.enw := (~fsmcCEnSync & ~fsmcAddrSync.extract(12) & fsmcAddrSync.extract(11) & (~fsmcWEnSync) ) mirrorDown.io.addrw := fsmcAddrSync(10,0) mirrorDown.io.dataw := fsmcdataInSync mirrorUp.io.enr := (~fsmcCEnSync & ~fsmcAddrSync.extract(12) & ~fsmcAddrSync.extract(11) & (~fsmcOEnSync) ) mirrorUp.io.addrr := fsmcAddrSync(10,0) val regOut = Wire(UInt(8.W)) io.FSMC.dataOut := Mux( fsmcAddrSync.extract(12), regOut, mirrorUp.io.datar) regOut := Mux1H(Seq( (fsmcAddrSync(10,0) === 0.U) -> status, (fsmcAddrSync(10,0) === 1.U) -> slvNum, )) when( (~fsmcCEnSync & fsmcAddrSync.extract(12) & (~fsmcWEnSync) ) & (fsmcAddrSync(10,0) === 0.U) ){ statusReg := fsmcdataInSync } when( (~fsmcCEnSync & fsmcAddrSync.extract(12) & (~fsmcWEnSync) ) & (fsmcAddrSync(10,0) === 1.U) ){ slvNumReg := fsmcdataInSync } } } trait BackBoardMstLVDS{ this: BackBoardMstBase => lvdsMst.io.rst_n := ~io.reset lvdsMst.io.oser_pclk := io.oser_pclk lvdsMst.io.oser_fclk := io.oser_fclk lvdsMst.io.ides_pclk := io.ides_pclk lvdsMst.io.ides_fclk := io.ides_fclk io.lvds_down_dout := lvdsMst.io.lvds_down_dout lvdsMst.io.lvds_up_din := io.lvds_up_din lvdsMst.io.tx_start := false.B withClockAndReset( io.ides_pclk.asClock, io.reset ){ val stateCur = RegInit(5.U(3.W)) val ( cnt, trigger ) = Counter(Range( 0,1023)) val addrr = RegInit(0.U) val addrw = RegInit(0.U) when( trigger ){ stateCur := 0.U addrr := 0.U addrw := 0.U lvdsMst.io.frame_info_update_en := true.B lvdsMst.io.slave_type_num := Cat( "b000".U(3.W), slvNum ) lvdsMst.io.slave_data_length := (8/8*4*8-1).U lvdsMst.io.tx_start := false.B } .elsewhen( stateCur === 0.U ){ stateCur := 1.U lvdsMst.io.frame_info_update_en := false.B lvdsMst.io.slave_type_num := 0.U lvdsMst.io.slave_data_length := 0.U lvdsMst.io.tx_start := true.B } .elsewhen( stateCur === 1.U ){ lvdsMst.io.frame_info_update_en := false.B lvdsMst.io.slave_type_num := 0.U lvdsMst.io.slave_data_length := 0.U lvdsMst.io.tx_start := false.B when( RegNext(lvdsMst.io.downstream_busy, false.B) & ~lvdsMst.io.downstream_busy ){ stateCur := 2.U } } .elsewhen( stateCur === 2.U ){ stateCur := 3.U lvdsMst.io.frame_info_update_en := true.B lvdsMst.io.slave_type_num := Cat( "b10".U(2.W), 0.U(6.W) ) lvdsMst.io.slave_data_length := 0.U lvdsMst.io.tx_start := false.B addrr := 0.U addrw := 0.U } .elsewhen( stateCur === 3.U ){ lvdsMst.io.frame_info_update_en := false.B lvdsMst.io.slave_type_num := 0.U lvdsMst.io.slave_data_length := 0.U lvdsMst.io.tx_start := true.B } .elsewhen( stateCur === 4.U ){ lvdsMst.io.frame_info_update_en := false.B lvdsMst.io.slave_type_num := 0.U lvdsMst.io.slave_data_length := 0.U lvdsMst.io.tx_start := false.B when( lvdsMst.io.tx_data_ready ){ addrr := addrr + 1.U } when( RegNext(lvdsMst.io.downstream_busy, false.B) & ~lvdsMst.io.downstream_busy ){ stateCur := 5.U } } .elsewhen( stateCur === 5.U ){ lvdsMst.io.frame_info_update_en := false.B lvdsMst.io.slave_type_num := 0.U lvdsMst.io.slave_data_length := 0.U lvdsMst.io.tx_start := false.B } .otherwise{ lvdsMst.io.frame_info_update_en := false.B lvdsMst.io.slave_type_num := 0.U lvdsMst.io.slave_data_length := 0.U lvdsMst.io.tx_start := false.B assert(false.B) } when( lvdsMst.io.rx_data_valid ){ assert( (stateCur === 4.U) || (stateCur === 5.U) ) addrw := addrw + 1.U } mirrorDown.io.enr := (stateCur === 3.U || stateCur === 4.U) lvdsMst.io.tx_data_in := mirrorDown.io.datar mirrorDown.io.addrr := addrr mirrorUp.io.enw := lvdsMst.io.rx_data_valid mirrorUp.io.dataw := lvdsMst.io.rx_data_out mirrorUp.io.addrw := addrw } } class BackBoardMst extends BackBoardMstBase with BackBoardMstFSMC with BackBoardMstLVDS