diff --git a/src/main/scala/backBoard/shin/NSpiInterface.scala b/src/main/scala/backBoard/shin/NSpiInterface.scala new file mode 100644 index 0000000..9bfba4d --- /dev/null +++ b/src/main/scala/backBoard/shin/NSpiInterface.scala @@ -0,0 +1,147 @@ +package BACK + +import chisel3._ +import chisel3.util._ + + + +abstract class SyncSpiInterfaceBase extends Module with RequireAsyncReset{ + val io = IO(new RegAccessInterfaceIO) + +} + +class SyncSSpiInterface extends SyncSpiInterfaceBase{ + val spi = IO(new SSPIInterfaceIO) + + // withClockAndReset(sck.asClock, reset.asBool){ + + + + spi.miso := exRego.extract(7) + + val bitSel = withClockAndReset(spi.sck.asClock, spi.csn){RegInit(0.U(3.W)) } + val byteSel = withClockAndReset(spi.sck.asClock, spi.csn){RegInit(0.U(12.W))} + val exRego = withClockAndReset(spi.sck.asClock, spi.csn){RegInit(0.U(8.W))} + val exRegi = withClockAndReset(spi.sck.asClock, spi.csn){RegInit(0.U(8.W))} + + + + when( true.B ){ + bitSel := bitSel + 1.U + } + + when( bitSel.andR ){ + byteSel := byteSel + 1.U + } + + when( true.B ){ + exRegi := Cat( exRegi(6 ,0), spi.mosi ) + } + + + when( bitSel === 0.U ){ + when((byteSel === 1.U || byteSel === 2.U) ){ + exRego := 0.U //地址1,cmd + } .elsewhen( isSpiRead ){ + exRego := datar_async + } + }.otherwise{ + exRego := exRego << 1 + } + + val addrw_async = withClockAndReset(spi.sck.asClock, spi.csn){ RegInit(0.U(16.W)) } + val addrr_async = withClockAndReset(spi.sck.asClock, spi.csn){ RegInit(0.U(16.W)) } + val dataw_async = withClockAndReset(spi.sck.asClock, spi.csn){ RegInit(0.U(8.W)) } + val datar_async = withClockAndReset(spi.sck.asClock, spi.csn){ RegInit(0.U(8.W)) } + val spiCmd = withClockAndReset(spi.sck.asClock, spi.csn){ RegInit(false.B) } + val isSpiWrite = ~spiCmd + val isSpiRead = spiCmd + + when( bitSel === 0.U ){ + when( byteSel === 1.U ){ + addrw_async := exRegi + } .elsewhen( byteSel === 2.U ) { + addrw_async := Cat(addrw_async(7,0), exRegi) + } .elsewhen( byteSel > 3.U ){ + addrw_async := addrw_async + 1.U + } + } + + when( bitSel === 0.U ){ + when( byteSel === 1.U ){ + addrr_async := exRegi + } .elsewhen( byteSel === 2.U ) { + addrr_async := Cat(addrr_async(7,0), exRegi) + } .elsewhen( byteSel > 2.U ){ + addrr_async := addrr_async + 1.U + } + } + + when( byteSel === 2.U & bitSel === 0.U ){ //CS为低,且SCK上跳的第0byte + spiCmd := spi.mosi + } + + + + when( bitSel === 0.U ){ + when( byteSel > 3.U & isSpiWrite ){ + dataw_async := exRegi + } + } + + + + io.dataw := exRegi + io.addrr := Mux( isSpiRead, addrr + 1.U, addrr ) + + // io.addrSel := + // Mux( isSpiRead, addrSel + 1.U, addrSel )//覆盖三种情况 + // val readData = RegEnable(io.datar, io.isEnR) + + + isEnW_async + isEnR_async + addrw_async + addrr_async + datar_async + dataw_async + + + isEnR_async := bitSel === 1.U & (byteSel >= 2.U) & isSpiRead + // isEnW_async := bitSel === 0.U & (byteSel >= 4.U) & isSpiWrite + + val isEnWSet_async = withClockAndReset(spi.sck.asClock, spi.csn){ RegInit(false.B) } + val isEnWSet_sync = ShiftRegisters(isEnWSet_async, 3, false.B, true.B) + val isEnWReset_async = withClockAndReset(spi.sck.asClock, spi.csn){ ShiftRegister(isEnWSet_sync(1), 2, false.B, true.B) } + + when( bitSel === 0.U & (byteSel >= 4.U) & isSpiWrite ){ + assert( ~isEnWSet_async, "Assert Failed @spi!\n" ) + isEnWSet_async := true.B + } .elsewhen(isEnWReSet_async){ + isEnWSet_async := false.B + } + + io.isEnW := ~isEnWSet_async(2) & isEnWSet_async(1) + io.addrw := addrw_async + io.dataw := dataw_async + + + val isEnRSet_async = withClockAndReset(spi.sck.asClock, spi.csn){ RegInit(false.B) } + val isEnRSet_sync = ShiftRegisters(isEnRSet_async, 3, false.B, true.B) + val isEnRReset_async = withClockAndReset(spi.sck.asClock, spi.csn){ ShiftRegister(isEnRSet_sync(1), 2, false.B, true.B) } + + when( bitSel === 1.U & (byteSel >= 2.U) & isSpiRead ){ + assert( ~isEnRSet_async, "Assert Failed @spi!\n" ) + isEnRSet_async := true.B + } .elsewhen(isEnRReSet_async){ + isEnRSet_async := false.B + } + + io.isEnR := ~isEnRSet_async(2) & isEnRSet_async(1) + io.addrr := addrr_async + datar_async := withClockAndReset(spi.sck.asClock, spi.csn){ RegEnable(io.datar, 0.U, isEnRReSet_async } + + +} + +