package BACK import chisel3._ import chisel3.util._ class FSMC_Port_Bundle extends Bundle{ val addr = Input(UInt(11.W)) val dataIn = Input(UInt(16.W)) val dataOut = Output(UInt(16.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 MirrorSRAMDown()) val mirrorUp = Module(new MirrorSRAMUp()) val status = Wire(UInt(16.W)) val slvNum = Wire(UInt(5.W)) mirrorDown.io.clockw := io.ides_pclk.asBool mirrorDown.io.clockr := io.oser_pclk.asBool mirrorUp.io.clockw := io.oser_pclk.asBool mirrorUp.io.clockr := io.ides_pclk.asBool } trait BackBoardMstFSMC{ this: BackBoardMstBase => withClockAndReset( io.ides_pclk.asClock, io.reset ){ val statusReg = RegInit(0.U(16.W)); status := statusReg val slvNumReg = RegInit(1.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 val isWriteSRAM = ~fsmcAddrSync.extract(10) & fsmcAddrSync.extract(9) val isReadSRAM = ~fsmcAddrSync.extract(10) & ~fsmcAddrSync.extract(9) val isAccessReg = fsmcAddrSync.extract(10) val activeAddr = fsmcAddrSync(8,0) val regOut = Wire(UInt(16.W)) mirrorDown.io.enw := (~fsmcCEnSync & isWriteSRAM & (~fsmcWEnSync) ) mirrorDown.io.addrw := activeAddr mirrorDown.io.dataw := fsmcdataInSync mirrorUp.io.enr := (~fsmcCEnSync & isReadSRAM & (~fsmcOEnSync) ) mirrorUp.io.addrr := activeAddr io.FSMC.dataOut := Mux( isAccessReg, regOut, mirrorUp.io.datar) regOut := Mux1H(Seq( ( activeAddr === 0.U) -> status, ( activeAddr === 1.U) -> slvNum, )) when( (~fsmcCEnSync & isAccessReg & (~fsmcWEnSync) ) & ( activeAddr === 0.U) ){ statusReg := fsmcdataInSync } when( (~fsmcCEnSync & isAccessReg & (~fsmcWEnSync) ) & ( activeAddr === 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 val trigger_wire = Wire(Bool()) val stateCur_wire = Wire( UInt(4.W) ) withClockAndReset( io.oser_pclk.asClock, io.reset ){ val stateCur = RegInit(3.U(4.W)) stateCur_wire := stateCur val ( _, trigger ) = Counter(Range( 0,1000) ) trigger_wire := trigger val isSync = RegInit(false.B) val frame_info_update_en = RegInit(false.B) val slave_type_num = RegInit(0.U(8.W)) val slave_data_length = RegInit(0.U(8.W)) val tx_start = RegInit(false.B) lvdsMst.io.frame_info_update_en := frame_info_update_en lvdsMst.io.slave_type_num := slave_type_num lvdsMst.io.slave_data_length := slave_data_length lvdsMst.io.tx_start := tx_start when( trigger ){ //reset stateCur := 0.U frame_info_update_en := false.B slave_type_num := 0.U slave_data_length := 0.U tx_start := false.B isSync := ~isSync } .elsewhen( stateCur === 0.U ){ //setting stateCur := 1.U frame_info_update_en := true.B slave_type_num := Mux(isSync, Cat( "b000".U(3.W), slvNum ), Cat( "b100".U(3.W), slvNum ) ) slave_data_length := ((8/8)*16-1).U tx_start := false.B } .elsewhen( stateCur === 1.U ){ // tx start stateCur := 2.U frame_info_update_en := false.B tx_start := true.B } .elsewhen( stateCur === 2.U ){ //waiting for busy drop tx_start := false.B when( RegNext(lvdsMst.io.downstream_busy, false.B) & ~lvdsMst.io.downstream_busy ){ stateCur := 3.U } } .elsewhen( stateCur === 3.U ){ } .otherwise{ assert(false.B) } val addrr = RegInit(0.U(10.W)) val addrw = RegInit(0.U(10.W)) when( trigger_wire ){ addrw := 0.U } .elsewhen( lvdsMst.io.rx_data_valid & ~isSync){ assert( (stateCur_wire === 2.U) || (stateCur_wire === 3.U) ) addrw := addrw + 1.U } when( trigger_wire ){ addrr := 0.U } .elsewhen( lvdsMst.io.tx_data_ready & ~isSync){ addrr := addrr + 1.U } mirrorDown.io.enr := (stateCur_wire === 1.U || stateCur_wire === 2.U) & ~isSync lvdsMst.io.tx_data_in := mirrorDown.io.datar mirrorDown.io.addrr := addrr mirrorUp.io.enw := lvdsMst.io.rx_data_valid & ~isSync mirrorUp.io.dataw := lvdsMst.io.rx_data_out mirrorUp.io.addrw := addrw } } class BackBoardMst extends BackBoardMstBase with BackBoardMstFSMC with BackBoardMstLVDS