2025-08-28 10:20:38 +08:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-28 15:51:17 +08:00
|
|
|
|
// isEnR_async := bitSel === 1.U & (byteSel >= 2.U) & isSpiRead
|
2025-08-28 10:20:38 +08:00
|
|
|
|
// 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 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|