编译通过
This commit is contained in:
@@ -154,6 +154,7 @@ class InterfaceIO extends Bundle{
|
|||||||
val ospi = new SSPIInterfaceIO
|
val ospi = new SSPIInterfaceIO
|
||||||
val oqspi = new QSPIInterfaceIO
|
val oqspi = new QSPIInterfaceIO
|
||||||
val iqspi = new QSPIInterfaceIO
|
val iqspi = new QSPIInterfaceIO
|
||||||
|
val aqspi = new QSPIInterfaceIO
|
||||||
|
|
||||||
val lvds = Flipped(new RegAccessInterfaceIO)
|
val lvds = Flipped(new RegAccessInterfaceIO)
|
||||||
|
|
||||||
@@ -223,10 +224,12 @@ abstract class InterfaceBase extends Module with RequireAsyncReset{
|
|||||||
val oSpi = Module(new SSpiInterface)
|
val oSpi = Module(new SSpiInterface)
|
||||||
val oQSpi = Module(new QSpiInterface)
|
val oQSpi = Module(new QSpiInterface)
|
||||||
val iQSpi = Module(new QSpiInterface)
|
val iQSpi = Module(new QSpiInterface)
|
||||||
|
val aQSpi = Module(new SyncQSpiInterface)
|
||||||
|
|
||||||
io.ospi <> oSpi.spi
|
io.ospi <> oSpi.spi
|
||||||
io.oqspi <> oQSpi.qspi
|
io.oqspi <> oQSpi.qspi
|
||||||
io.iqspi <> iQSpi.qspi
|
io.iqspi <> iQSpi.qspi
|
||||||
|
io.aqspi <> aQSpi.qspi
|
||||||
|
|
||||||
val cReg = Wire(new CommonRegisterBundle); io.cReg := cReg
|
val cReg = Wire(new CommonRegisterBundle); io.cReg := cReg
|
||||||
val mReg = Wire(new MasterRegisterBundle); io.mReg := mReg
|
val mReg = Wire(new MasterRegisterBundle); io.mReg := mReg
|
||||||
@@ -557,30 +560,35 @@ trait InterfaceMCUop{ this: InterfaceBase =>
|
|||||||
( cReg.spiSel === 0.U ) -> iQSpi.io.isEnW,
|
( cReg.spiSel === 0.U ) -> iQSpi.io.isEnW,
|
||||||
( cReg.spiSel === 1.U ) -> oSpi.io.isEnW,
|
( cReg.spiSel === 1.U ) -> oSpi.io.isEnW,
|
||||||
( cReg.spiSel === 2.U ) -> oQSpi.io.isEnW,
|
( cReg.spiSel === 2.U ) -> oQSpi.io.isEnW,
|
||||||
|
( cReg.spiSel === 3.U ) -> aQSpi.io.isEnW,
|
||||||
))
|
))
|
||||||
|
|
||||||
addrr := Mux1H(Seq(
|
addrr := Mux1H(Seq(
|
||||||
( cReg.spiSel === 0.U ) -> iQSpi.io.addrr,
|
( cReg.spiSel === 0.U ) -> iQSpi.io.addrr,
|
||||||
( cReg.spiSel === 1.U ) -> oSpi.io.addrr,
|
( cReg.spiSel === 1.U ) -> oSpi.io.addrr,
|
||||||
( cReg.spiSel === 2.U ) -> oQSpi.io.addrr,
|
( cReg.spiSel === 2.U ) -> oQSpi.io.addrr,
|
||||||
|
( cReg.spiSel === 3.U ) -> aQSpi.io.addrr,
|
||||||
))
|
))
|
||||||
|
|
||||||
addrw := Mux1H(Seq(
|
addrw := Mux1H(Seq(
|
||||||
( cReg.spiSel === 0.U ) -> iQSpi.io.addrw,
|
( cReg.spiSel === 0.U ) -> iQSpi.io.addrw,
|
||||||
( cReg.spiSel === 1.U ) -> oSpi.io.addrw,
|
( cReg.spiSel === 1.U ) -> oSpi.io.addrw,
|
||||||
( cReg.spiSel === 2.U ) -> oQSpi.io.addrw,
|
( cReg.spiSel === 2.U ) -> oQSpi.io.addrw,
|
||||||
|
( cReg.spiSel === 3.U ) -> aQSpi.io.addrw,
|
||||||
))
|
))
|
||||||
|
|
||||||
dataw := Mux1H(Seq(
|
dataw := Mux1H(Seq(
|
||||||
( cReg.spiSel === 0.U ) -> iQSpi.io.dataw,
|
( cReg.spiSel === 0.U ) -> iQSpi.io.dataw,
|
||||||
( cReg.spiSel === 1.U ) -> oSpi.io.dataw,
|
( cReg.spiSel === 1.U ) -> oSpi.io.dataw,
|
||||||
( cReg.spiSel === 2.U ) -> oQSpi.io.dataw,
|
( cReg.spiSel === 2.U ) -> oQSpi.io.dataw,
|
||||||
|
( cReg.spiSel === 3.U ) -> aQSpi.io.dataw,
|
||||||
))
|
))
|
||||||
|
|
||||||
isEnR := Mux1H(Seq(
|
isEnR := Mux1H(Seq(
|
||||||
( cReg.spiSel === 0.U ) -> iQSpi.io.isEnR,
|
( cReg.spiSel === 0.U ) -> iQSpi.io.isEnR,
|
||||||
( cReg.spiSel === 1.U ) -> oSpi.io.isEnR,
|
( cReg.spiSel === 1.U ) -> oSpi.io.isEnR,
|
||||||
( cReg.spiSel === 2.U ) -> oQSpi.io.isEnR,
|
( cReg.spiSel === 2.U ) -> oQSpi.io.isEnR,
|
||||||
|
( cReg.spiSel === 3.U ) -> aQSpi.io.isEnR,
|
||||||
))
|
))
|
||||||
|
|
||||||
datar := MuxCase( 0.U, Array(
|
datar := MuxCase( 0.U, Array(
|
||||||
@@ -598,6 +606,7 @@ trait InterfaceMCUop{ this: InterfaceBase =>
|
|||||||
iQSpi.io.datar := Mux(cReg.spiSel === 0.U, datar, 0.U)
|
iQSpi.io.datar := Mux(cReg.spiSel === 0.U, datar, 0.U)
|
||||||
oSpi.io.datar := Mux(cReg.spiSel === 1.U, datar, 0.U)
|
oSpi.io.datar := Mux(cReg.spiSel === 1.U, datar, 0.U)
|
||||||
oQSpi.io.datar := Mux(cReg.spiSel === 2.U, datar, 0.U)
|
oQSpi.io.datar := Mux(cReg.spiSel === 2.U, datar, 0.U)
|
||||||
|
aQSpi.io.datar := Mux(cReg.spiSel === 3.U, datar, 0.U)
|
||||||
|
|
||||||
// when( isEnW ){
|
// when( isEnW ){
|
||||||
// printf(s"SPI/QSPI Write 0x%x, @0x%x\n", dataw, addrw)
|
// printf(s"SPI/QSPI Write 0x%x, @0x%x\n", dataw, addrw)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class TopBase_IO_Bundle extends Bundle{
|
|||||||
val iqspi = new QSPIInterfaceIO
|
val iqspi = new QSPIInterfaceIO
|
||||||
val ospi = new SSPIInterfaceIO
|
val ospi = new SSPIInterfaceIO
|
||||||
val oqspi = new QSPIInterfaceIO
|
val oqspi = new QSPIInterfaceIO
|
||||||
|
val aqspi = new QSPIInterfaceIO
|
||||||
|
|
||||||
val iSync = Output(Vec(4, Bool()))
|
val iSync = Output(Vec(4, Bool()))
|
||||||
|
|
||||||
@@ -98,6 +99,7 @@ abstract class MstSlvSwitchBase extends Module with RequireAsyncReset{
|
|||||||
io.ospi <> interface.io.ospi
|
io.ospi <> interface.io.ospi
|
||||||
io.iqspi <> interface.io.iqspi
|
io.iqspi <> interface.io.iqspi
|
||||||
io.oqspi <> interface.io.oqspi
|
io.oqspi <> interface.io.oqspi
|
||||||
|
io.aqspi <> interface.io.aqspi
|
||||||
|
|
||||||
io.iSync := interface.io.sync
|
io.iSync := interface.io.sync
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,39 @@ import chisel3.util._
|
|||||||
abstract class SyncSpiInterfaceBase extends Module with RequireAsyncReset{
|
abstract class SyncSpiInterfaceBase extends Module with RequireAsyncReset{
|
||||||
val io = IO(new RegAccessInterfaceIO)
|
val io = IO(new RegAccessInterfaceIO)
|
||||||
val qspi = IO(new QSPIInterfaceIO)
|
val qspi = IO(new QSPIInterfaceIO)
|
||||||
|
|
||||||
|
val bitSel = withClockAndReset((~qspi.sck).asClock, qspi.csn){RegInit(0.U(3.W)) }
|
||||||
|
val byteSel = withClockAndReset((~qspi.sck).asClock, qspi.csn){RegInit(0.U(12.W))}
|
||||||
|
val exRego = withClockAndReset((~qspi.sck).asClock, qspi.csn){RegInit(0.U(8.W))}
|
||||||
|
val exRegi = withClockAndReset((~qspi.sck).asClock, qspi.csn){RegInit(0.U(8.W))}
|
||||||
|
val addrw_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(0.U(16.W)) } }
|
||||||
|
val addrr_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(0.U(16.W)) } }
|
||||||
|
val dataw_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(0.U(8.W)) } }
|
||||||
|
val isEnR_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(false.B) } }
|
||||||
|
val isEnW_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(false.B) } }
|
||||||
|
|
||||||
|
val spiLen = withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(2.U(12.W)) }
|
||||||
|
val spiCnt = withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(0.U(12.W)) }
|
||||||
|
val isSpiWrite = withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(false.B) }
|
||||||
|
val isSpiRead = withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(false.B) }
|
||||||
|
val isPing_async = withClockAndReset((~qspi.sck).asClock, qspi.csn){ RegInit(false.B) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
val isPong_sync = RegInit(false.B)
|
||||||
|
val isEnW_sync = for( i <- 0 until 2 ) yield { ShiftRegisters( isEnW_async(i), 3, false.B, true.B ) }
|
||||||
|
val isEnR_sync = for( i <- 0 until 2 ) yield { ShiftRegisters( isEnR_async(i), 3, false.B, true.B ) }
|
||||||
|
val datar_sync = for( _ <- 0 until 2 ) yield { RegInit(0.U(8.W)) }
|
||||||
|
val isEnW = for( i <- 0 until 2 ) yield { ~isEnW_sync(i)(2) & isEnW_sync(i)(1) }
|
||||||
|
val isEnR = for( i <- 0 until 2 ) yield { ~isEnR_sync(i)(2) & isEnR_sync(i)(1) }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trait SyncSpiAsync{ this: SyncSpiInterfaceBase =>
|
trait SyncSpiAsync{ this: SyncSpiInterfaceBase =>
|
||||||
|
|
||||||
val bitSel = withClockAndReset(~qspi.sck.asClock, qspi.csn){RegInit(0.U(3.W)) }
|
|
||||||
val byteSel = withClockAndReset(~qspi.sck.asClock, qspi.csn){RegInit(0.U(12.W))}
|
|
||||||
val exRego = withClockAndReset(~qspi.sck.asClock, qspi.csn){RegInit(0.U(8.W))}
|
|
||||||
val exRegi = withClockAndReset(~qspi.sck.asClock, qspi.csn){RegInit(0.U(8.W))}
|
|
||||||
|
|
||||||
qspi.miso := exRego(7, 4)
|
qspi.miso := exRego(7, 4)
|
||||||
qspi.isDirIn := ~isSpiRead
|
qspi.isDirIn := ~isSpiRead
|
||||||
@@ -49,17 +74,7 @@ trait SyncSpiAsync{ this: SyncSpiInterfaceBase =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val addrw_async = for( _ <- 0 until 2 ) yield { withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(0.U(16.W)) } }
|
|
||||||
val addrr_async = for( _ <- 0 until 2 ) yield { withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(0.U(16.W)) } }
|
|
||||||
val dataw_async = for( _ <- 0 until 2 ) yield { withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(0.U(8.W)) } }
|
|
||||||
val isEnR_async = for( _ <- 0 until 2 ) yield { withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(false.B) } }
|
|
||||||
val isEnW_async = for( _ <- 0 until 2 ) yield { withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(false.B) } }
|
|
||||||
|
|
||||||
val spiLen = withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(2.U(12.W)) }
|
|
||||||
val spiCnt = withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(0.U(12.W)) }
|
|
||||||
val isSpiWrite = withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(false.B) }
|
|
||||||
val isSpiRead = withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(false.B) }
|
|
||||||
val isPing_async = withClockAndReset(~qspi.sck.asClock, qspi.csn){ RegInit(false.B) }
|
|
||||||
|
|
||||||
when( isEnR_async(0) | isEnW_async(0) | isEnR_async(1) | isEnW_async(1) ){
|
when( isEnR_async(0) | isEnW_async(0) | isEnR_async(1) | isEnW_async(1) ){
|
||||||
spiCnt := spiCnt + 1.U
|
spiCnt := spiCnt + 1.U
|
||||||
@@ -73,34 +88,13 @@ trait SyncSpiAsync{ this: SyncSpiInterfaceBase =>
|
|||||||
spiLen := Cat( spiLen(11, 4), exRegi )
|
spiLen := Cat( spiLen(11, 4), exRegi )
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
trait SyncSpiSync{ this: SyncSpiInterfaceBase =>
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class SyncQSpiInterface extends SyncSpiInterfaceBase
|
|
||||||
with SyncSpiAsync
|
|
||||||
with SyncSpiSync{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( bitSel === 0.U ){
|
when( bitSel === 0.U ){
|
||||||
when( byteSel === 1.U ){
|
when( byteSel === 1.U ){
|
||||||
addrw_async(0) := exRegi
|
addrw_async(0) := exRegi
|
||||||
addrw_async(1) := exRegi
|
addrw_async(1) := exRegi
|
||||||
} .elsewhen( byteSel === 2.U ) {
|
} .elsewhen( byteSel === 2.U ) {
|
||||||
addrw_async(0) := Cat(addrw_async(7,0), exRegi)
|
addrw_async(0) := Cat(addrw_async(0)(7,0), exRegi)
|
||||||
addrw_async(1) := Cat(addrw_async(7,0), exRegi)
|
addrw_async(1) := Cat(addrw_async(1)(7,0), exRegi)
|
||||||
} .elsewhen( byteSel >= 5.U ){
|
} .elsewhen( byteSel >= 5.U ){
|
||||||
when( ~isPing_async ){
|
when( ~isPing_async ){
|
||||||
addrw_async(0) := addrw_async(0) + 2.U
|
addrw_async(0) := addrw_async(0) + 2.U
|
||||||
@@ -115,8 +109,8 @@ with SyncSpiSync{
|
|||||||
addrr_async(0) := exRegi
|
addrr_async(0) := exRegi
|
||||||
addrr_async(1) := exRegi
|
addrr_async(1) := exRegi
|
||||||
} .elsewhen( byteSel === 2.U ) {
|
} .elsewhen( byteSel === 2.U ) {
|
||||||
addrr_async(0) := Cat(addrr_async(7,0), exRegi)
|
addrr_async(0) := Cat(addrr_async(0)(7,0), exRegi)
|
||||||
addrr_async(1) := Cat(addrr_async(7,0), exRegi)
|
addrr_async(1) := Cat(addrr_async(1)(7,0), exRegi)
|
||||||
}
|
}
|
||||||
} .otherwise{
|
} .otherwise{
|
||||||
when( byteSel >= 2.U ){
|
when( byteSel >= 2.U ){
|
||||||
@@ -128,8 +122,6 @@ with SyncSpiSync{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
when( byteSel === 2.U & bitSel === 0.U ){ //CS为低,且SCK上跳的第0byte
|
when( byteSel === 2.U & bitSel === 0.U ){ //CS为低,且SCK上跳的第0byte
|
||||||
when( qspi.mosi.extract(3) ){
|
when( qspi.mosi.extract(3) ){
|
||||||
isSpiRead := true.B
|
isSpiRead := true.B
|
||||||
@@ -145,7 +137,6 @@ with SyncSpiSync{
|
|||||||
} .otherwise{
|
} .otherwise{
|
||||||
dataw_async(1) := exRegi
|
dataw_async(1) := exRegi
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +162,6 @@ with SyncSpiSync{
|
|||||||
isEnW_async(1) := false.B
|
isEnW_async(1) := false.B
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
when( isEnR_async(0) | isEnW_async(0) ){
|
when( isEnR_async(0) | isEnW_async(0) ){
|
||||||
assert( ~isPing_async )
|
assert( ~isPing_async )
|
||||||
isPing_async := true.B
|
isPing_async := true.B
|
||||||
@@ -180,15 +170,10 @@ with SyncSpiSync{
|
|||||||
isPing_async := false.B
|
isPing_async := false.B
|
||||||
}
|
}
|
||||||
|
|
||||||
val isPong_sync = RegInit(false.B)
|
|
||||||
|
|
||||||
val isEnW_sync = for( _ <- 0 until 2 ) yield { ShiftRegisters( isEnW_async(i), 3, false.B, true.B ) }
|
}
|
||||||
val isEnR_sync = for( _ <- 0 until 2 ) yield { ShiftRegisters( isEnR_async(i), 3, false.B, true.B ) }
|
|
||||||
|
|
||||||
val datar_sync = for( _ <- 0 until 2 ) yield { RegInit(0.U(8.W)) }
|
trait SyncSpiSync{ this: SyncSpiInterfaceBase =>
|
||||||
|
|
||||||
val isEnW = for( _ <- 0 until 2 ) yield { ~isEnW_sync(i)(2) & isEnW_sync(i)(1) }
|
|
||||||
val isEnR = for( _ <- 0 until 2 ) yield { ~isEnR_sync(i)(2) & isEnR_sync(i)(1) }
|
|
||||||
|
|
||||||
io.isEnW :=
|
io.isEnW :=
|
||||||
( ~isPong_sync & isEnW(0) ) |
|
( ~isPong_sync & isEnW(0) ) |
|
||||||
@@ -214,7 +199,6 @@ with SyncSpiSync{
|
|||||||
isPong_sync -> dataw_async(1),
|
isPong_sync -> dataw_async(1),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
when( io.isEnR ){
|
when( io.isEnR ){
|
||||||
when( RegNext(~isPong_sync, false.B) ){
|
when( RegNext(~isPong_sync, false.B) ){
|
||||||
datar_sync(0) := io.datar
|
datar_sync(0) := io.datar
|
||||||
@@ -230,4 +214,9 @@ with SyncSpiSync{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SyncQSpiInterface extends SyncSpiInterfaceBase
|
||||||
|
with SyncSpiAsync
|
||||||
|
with SyncSpiSync{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user