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, 4, false.B, true.B ) val csShift = ShiftRegisters( io.CS, 4, 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(3) & ~CDROutValidSetReg, false.B); CDRInValidReset := CDRInValidResetReg when( CDROutValidSetReg & CDROutValidResetAsync ){ CDROutValidSetReg := false.B centReg.op := 1.U } .elsewhen( ~csShift(3) & csShift(2) ){ CDROutValidSetReg := true.B } io.MISO := centReg.asUInt.extract( 6+8+32+2+16-1 ) val sckPosedge = ~sckShift(3) & sckShift(2) val sckNegedge = sckShift(3) & ~sckShift(2) when( ~csShift(3) ){ when( sckNegedge ){ centReg := Cat(centReg.asUInt( 6+8+32+2+16-2, 0 ), io.MOSI).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 }