Files
eb001/src/main/scala/backBoard/SpiSlv.scala
2023-08-07 10:15:56 +08:00

89 lines
2.6 KiB
Scala

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
}