package BACK import chisel3._ import chisel3.util._ class CDR_Master_Interface_Bundle extends CDRData{ val op = UInt(2.W) } class SpiSlvIO extends Bundle{ val CS = Input(Bool()) val MISO = Output(Bool()) val MOSI = Input(Bool()) val SCK = Input(Bool()) val clk4 = Input(Bool()) val CDRIn = Flipped(Decoupled(new CDRData)) val CDROut = Decoupled(new CDRData) } class SpiSlv extends Module{ val io: SpiSlvIO = IO(new SpiSlvIO) val CDROutValidSet = Wire(Bool()) val CDROutValidSetAsync = ShiftRegister(CDROutValidSet, 2, false.B, true.B) val CDROutValidReset = RegNext(CDROutValidSetAsync, false.B) // val CDRInValidSet = RegInit(false.B) val CDRInValidReset = Wire(Bool()) val CDRInValidResetAsync = ShiftRegister( CDRInValidReset, 2, false.B, true.B) val cent = Wire(new CDR_Master_Interface_Bundle) withClockAndReset( io.clk4.asClock, reset ){ val centReg = RegInit(0.U.asTypeOf(new CDR_Master_Interface_Bundle)); cent := centReg val sckShift = ShiftRegisters( io.SCK, 3, false.B, true.B ) val csShift = ShiftRegisters( io.CS, 3, true.B, true.B ) val mosiShift = ShiftRegisters( io.MOSI, 2, true.B, true.B ) val CDROutValidSetReg = RegInit(false.B); CDROutValidSet := CDROutValidSetReg val CDROutValidResetAsync = ShiftRegister( CDROutValidReset, 2, false.B, true.B ) val CDRInValidSetAsync = ShiftRegister( io.CDRIn.valid , 2, false.B, true.B ) val CDRInValidResetReg = RegNext(CDRInValidSetAsync & csShift(1) & ~CDROutValidSetReg, false.B); CDRInValidReset := CDRInValidResetReg when( CDROutValidSetReg & CDROutValidResetAsync ){ CDROutValidSetReg := false.B centReg.op := 1.U } .elsewhen( ~csShift(2) & csShift(1) ){ CDROutValidSetReg := true.B } io.MISO := centReg.asUInt.extract( 6+8+32+2+16-1 ) val sckPosedge = ~sckShift(2) & sckShift(1) val sckNegedge = sckShift(2) & ~sckShift(1) when( ~csShift(1) ){ when( sckPosedge ){ centReg := Cat(centReg.asUInt( 6+8+32+2+16-2, 0 ), mosiShift(1)).asTypeOf(new CDR_Master_Interface_Bundle) } } .otherwise{ when( CDRInValidSetAsync & ~CDROutValidSetReg ){ centReg.address := io.CDRIn.bits.address centReg.register := io.CDRIn.bits.register centReg.data := io.CDRIn.bits.data centReg.op := 0.U } } } val CDROutValid = RegInit(false.B); io.CDROut.valid := CDROutValid val CDROutInfo = Reg(new CDRData); io.CDROut.bits := CDROutInfo when( io.CDROut.fire ){ CDROutValid := false.B } .elsewhen( CDROutValidSet & ~CDROutValidSetAsync ){ CDROutValid := true.B CDROutInfo := cent } io.CDRIn.ready := CDRInValidResetAsync }