diff --git a/src/main/scala/backBoard/shin/Interface.scala b/src/main/scala/backBoard/shin/Interface.scala index 123416d..69d9bae 100644 --- a/src/main/scala/backBoard/shin/Interface.scala +++ b/src/main/scala/backBoard/shin/Interface.scala @@ -9,7 +9,7 @@ class CommonRegisterBundle extends Bundle{ val hwSerial = UInt(48.W) val busRate = UInt(16.W) - // val spiSel = UInt(2.W) + val spiSel = UInt(2.W) // val isSoftReset = Bool() val encryptKey = UInt(128.W) @@ -93,7 +93,9 @@ class SlaveRegisterBundle extends Bundle{ class InterfaceIO extends Bundle{ - val ospi = new SPIInterfaceIO + val ospi = new SSPIInterfaceIO + val oqspi = new QSPIInterfaceIO + val iqspi = new QSPIInterfaceIO @@ -123,8 +125,13 @@ class InterfaceIO extends Bundle{ abstract class InterfaceBase extends Module{ val io: InterfaceIO = IO(new InterfaceIO) - val oSpi = Module(new SpiInterface) - io.ospi <> oSpi.io.spi + val oSpi = Module(new SSpiInterface) + val oQSpi = Module(new QSpiInterface) + val iQSpi = Module(new QSpiInterface) + + io.ospi <> oSpi.spi + io.oqspi <> oQSpi.qspi + io.iqspi <> iQSpi.qspi val cReg = Wire(new CommonRegisterBundle) val mReg = Wire(new MasterRegisterBundle) @@ -152,6 +159,7 @@ abstract class InterfaceBase extends Module{ (addr === "h20".U & isMstMode) -> Cat(mReg.rxSM, mReg.txSM, 0.U(1.W) ), (addr === "h21".U & isMstMode) -> mReg.txLength, + (addr === "h27".U ) -> cReg.spiSel ) ++ @@ -179,24 +187,53 @@ trait InterfaceMCUop{ this: InterfaceBase => - oSpi.io.datar := - MuxCase( 0.U, Array( - ((oSpi.io.addrSel & "hFF00".U) === "h0000".U) -> RegEnable( AcquireReg(addr = oSpi.io.addrSel), 0.U, oSpi.io.isEnR ), - ((oSpi.io.addrSel & "hFF00".U) === "h0800".U) -> io.sram_r(0).datar, - ((oSpi.io.addrSel & "hFF00".U) === "h1000".U) -> 0.U, - ((oSpi.io.addrSel & "hFF00".U) === "h1800".U) -> io.sram_r(1).datar, - ((oSpi.io.addrSel & "hFF00".U) === "h2000".U) -> 0.U, - ((oSpi.io.addrSel & "hFF00".U) === "h2800".U) -> io.sram_r(2).datar, - ((oSpi.io.addrSel & "hFF00".U) === "h3000".U) -> 0.U, - ((oSpi.io.addrSel & "hFF00".U) === "h3800".U) -> io.sram_r(3).datar, - ((oSpi.io.addrSel & "hFF00".U) === "h4000".U) -> 0.U, + + + + val isEnW = Mux1H(Seq( + ( cReg.spiSel === 0.U ) -> iQSpi.io.isEnW, + ( cReg.spiSel === 1.U ) -> oSpi.io.isEnW, + ( cReg.spiSel === 2.U ) -> oQSpi.io.isEnW, + )) + + val addrSel = Mux1H(Seq( + ( cReg.spiSel === 0.U ) -> iQSpi.io.addrSel, + ( cReg.spiSel === 1.U ) -> oSpi.io.addrSel, + ( cReg.spiSel === 2.U ) -> oQSpi.io.addrSel, + )) + + val dataw = Mux1H(Seq( + ( cReg.spiSel === 0.U ) -> iQSpi.io.dataw, + ( cReg.spiSel === 1.U ) -> oSpi.io.dataw, + ( cReg.spiSel === 2.U ) -> oQSpi.io.dataw, + )) + + val isEnR = Mux1H(Seq( + ( cReg.spiSel === 0.U ) -> iQSpi.io.isEnR, + ( cReg.spiSel === 1.U ) -> oSpi.io.isEnR, + ( cReg.spiSel === 2.U ) -> oQSpi.io.isEnR, + )) + + val datar = MuxCase( 0.U, Array( + ((addrSel & "hFF00".U) === "h0000".U) -> RegEnable( AcquireReg(addr = oSpi.io.addrSel), 0.U, oSpi.io.isEnR ), + ((addrSel & "hFF00".U) === "h0800".U) -> io.sram_r(0).datar, + ((addrSel & "hFF00".U) === "h1000".U) -> 0.U, + ((addrSel & "hFF00".U) === "h1800".U) -> io.sram_r(1).datar, + ((addrSel & "hFF00".U) === "h2000".U) -> 0.U, + ((addrSel & "hFF00".U) === "h2800".U) -> io.sram_r(2).datar, + ((addrSel & "hFF00".U) === "h3000".U) -> 0.U, + ((addrSel & "hFF00".U) === "h3800".U) -> io.sram_r(3).datar, + ((addrSel & "hFF00".U) === "h4000".U) -> 0.U, )) + iQSpi.io.datar := Mux(cReg.spiSel === 0.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) + + + + - val isEnW = oSpi.io.isEnW - val addrSel = oSpi.io.addrSel - val dataw = oSpi.io.dataw - val isEnR = oSpi.io.isEnR cReg.mstOrSlv := RegEnable( dataw(1,0), 0.U, isEnW & addrSel === "h0".U & cReg.mstOrSlv === 0.U ) cReg.hwVersion := RegEnable( dataw , 0.U, isEnW & addrSel === "h1".U & cReg.mstOrSlv === 0.U ) @@ -221,6 +258,8 @@ trait InterfaceMCUop{ this: InterfaceBase => }.reverse ) + cReg.spiSel := + RegEnable( dataw(1,0), 0.U, isEnW & addrSel === "h27".U & cReg.mstOrSlv === 0.U ) mReg.txSM := RegEnable( dataw(2,1), 0.U, isEnW & addrSel === "h20".U ) diff --git a/src/main/scala/backBoard/shin/ShinTop.scala b/src/main/scala/backBoard/shin/ShinTop.scala index af367a2..c4adf37 100644 --- a/src/main/scala/backBoard/shin/ShinTop.scala +++ b/src/main/scala/backBoard/shin/ShinTop.scala @@ -25,7 +25,9 @@ class ShinTopIO extends Bundle{ - val ospi = new SPIInterfaceIO + val iqspi = new QSPIInterfaceIO + val ospi = new SSPIInterfaceIO + val oqspi = new QSPIInterfaceIO // val req = Flipped(Valid(new Bundle{ @@ -73,8 +75,9 @@ abstract class ShinTopBase extends Module{ io.dDatOut := false.B } - io.ospi <> interface.io.ospi - + io.ospi <> interface.io.ospi + io.iqspi <> interface.io.iqspi + io.oqspi <> interface.io.oqspi val sram = Seq( for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) }, diff --git a/src/main/scala/backBoard/shin/SpiInterface.scala b/src/main/scala/backBoard/shin/SpiInterface.scala index a33a32f..cc13a17 100644 --- a/src/main/scala/backBoard/shin/SpiInterface.scala +++ b/src/main/scala/backBoard/shin/SpiInterface.scala @@ -3,7 +3,16 @@ package BACK import chisel3._ import chisel3.util._ -class SPIInterfaceIO extends Bundle{ +class QSPIInterfaceIO extends Bundle{ + val sck = Input(Bool()) + val mosi = Input(UInt(4.W)) + val miso = Output(UInt(4.W)) + val isDirIn = Output(Bool()) + val csn = Input(Bool()) +} + + +class SSPIInterfaceIO extends Bundle{ val sck = Input(Bool()) val mosi = Input(Bool()) val miso = Output(Bool()) @@ -11,10 +20,8 @@ class SPIInterfaceIO extends Bundle{ } -class SpiInterface extends Module{ +abstract class SpiInterfaceBase extends Module{ val io = IO(new Bundle{ - val spi = new SPIInterfaceIO - val addrSel = Output(UInt(16.W)) val dataw = Output( UInt(8.W) ) val datar = Input( UInt(8.W) ) @@ -22,26 +29,14 @@ class SpiInterface extends Module{ val isEnR = Output(Bool()) }) - - val sck = io.spi.sck - val mosi = io.spi.mosi - val csn = io.spi.csn - - -// val spiRegDown = Module(new SpiSRAMDown) -// val spiRegUp = Module(new SpiSRAMUp) - - -// spiRegDown.io.clockr := clk100M -// spiRegDown.io.clockw := clock.asBool - -// spiRegUp.io.clockr := clock.asBool -// spiRegUp.io.clockw := clk100M + val sck = Wire(Bool()) + val csn = Wire(Bool()) + //数据信号相对SCK的稳定应该由外部主机保证,因此认为SCK采样时刻,数据都是稳定正确的 val shiftSCK = ShiftRegisters(sck, 3, false.B, true.B) val shiftCSn = ShiftRegisters(csn, 3, true.B, true.B) - val shiftMOSI = ShiftRegisters(mosi, 3) + val isSckPosedge = ~shiftSCK(2) & shiftSCK(1) @@ -50,7 +45,7 @@ class SpiInterface extends Module{ val exReg = Reg(UInt(8.W)) - io.spi.miso := exReg.extract(exReg.getWidth-1) + val addrSel = Reg(UInt(16.W)); io.addrSel := addrSel val spiCmd = Reg(UInt(8.W)) @@ -62,36 +57,28 @@ class SpiInterface extends Module{ val byteSel = Reg(UInt(12.W)) -// spiRegDown.io.addrr := Cat(pageSel, byteSel) -// spiRegDown.io.enr := spiCmd === 0.U & isSckPosedgeNext(0) - -// spiRegUp.io.addrw := Cat(pageSel, byteSel - 1.U) -// spiRegUp.io.dataw := withClockAndReset( clk100M.asClock, reset ){ RegEnable(exReg_100M, bitSel === 0.U) } - -// spiRegUp.io.enw := isSckPosedgeNext(1) & ~shiftCSn(1+1) & bitSel === 0.U & spiCmd === 1.U - - io.isEnR := isSckPosedgeNext(0) & ~shiftCSn(1+1) & bitSel === 7.U & isSpiRead & byteSel >= 3.U - io.isEnW := isSckPosedgeNext(0) & ~shiftCSn(1+1) & bitSel === 7.U & isSpiWrite & byteSel >= 3.U - io.dataw := exReg + io.isEnR := isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel.andR & isSpiRead & byteSel >= 3.U + io.isEnW := isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel.andR & isSpiWrite & byteSel >= 3.U + io.dataw := exReg when( shiftCSn(2) & ~shiftCSn(1) ){ - bitSel := 0.U byteSel := 0.U } .elsewhen( isSckPosedge & ~shiftCSn(1) ){ - bitSel := bitSel + 1.U - when( bitSel === 7.U ){ + when( bitSel.andR ){ byteSel := byteSel + 1.U } } + + when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳 addrSel := 0.U - } .elsewhen(isSckPosedgeNext(0) & ~shiftCSn(1+1) & bitSel === 7.U & byteSel === 0.U){ //CS为低,且SCK上跳的第0byte + } .elsewhen(isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel.andR & byteSel === 0.U){ //CS为低,且SCK上跳的第0byte addrSel := exReg - } .elsewhen(isSckPosedgeNext(0) & ~shiftCSn(1+1) & bitSel === 7.U & byteSel === 1.U) {//CS为低,且SCK上跳的第0byte + } .elsewhen(isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel.andR & byteSel === 1.U) {//CS为低,且SCK上跳的第0byte addrSel := Cat(exReg, addrSel(7,0)) } .otherwise{ // byteSel > 1.U - when( isSckPosedgeNext(1) & byteSel > 2.U & bitSel === 7.U ){ + when( isSckPosedgeNext(1) & byteSel > 2.U & bitSel.andR ){ addrSel := addrSel + 1.U } } @@ -99,13 +86,34 @@ class SpiInterface extends Module{ when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳 spiCmd := "hFF".U - } .elsewhen( isSckPosedgeNext(0) & ~shiftCSn(1) & byteSel === 2.U & bitSel === 7.U ){ //CS为低,且SCK上跳的第0byte + } .elsewhen( isSckPosedgeNext(0) & ~shiftCSn(1) & byteSel === 2.U & bitSel.andR ){ //CS为低,且SCK上跳的第0byte spiCmd := exReg } + + + +} + +class SSpiInterface extends SpiInterfaceBase{ + val spi = IO(new SSPIInterfaceIO) + + sck := spi.sck + csn := spi.csn + + spi.miso := exReg.extract(7) + + when( shiftCSn(2) & ~shiftCSn(1) ){ + bitSel := 0.U + } .elsewhen( isSckPosedge & ~shiftCSn(1) ){ + bitSel := bitSel + 1.U + } + + val shiftMOSI = ShiftRegisters(spi.mosi, 3) + when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳 //第一个byte exReg := 0.U - } .elsewhen( isSckPosedgeNext(1) & ~shiftCSn(1) & bitSel === 7.U ){ //CS为低,且SCK上跳补一拍 的第0bit + } .elsewhen( isSckPosedgeNext(1) & ~shiftCSn(2) & bitSel.andR ){ //CS为低,且SCK上跳补一拍 的第0bit when( byteSel === 0.U || byteSel === 1.U ){ //第1、2byte exReg := 0.U } .otherwise{ @@ -121,40 +129,43 @@ class SpiInterface extends Module{ exReg := Cat( exReg(6 ,0), shiftMOSI(1) ) } +} + +class QSpiInterface extends SpiInterfaceBase{ + val qspi = IO(new QSPIInterfaceIO) + + sck := qspi.sck + csn := qspi.csn + qspi.miso := exReg(7, 4) + qspi.isDirIn := isSpiWrite + + when( shiftCSn(2) & ~shiftCSn(1) ){ + bitSel := 0.U + } .elsewhen( isSckPosedge & ~shiftCSn(1) ){ + bitSel := ~bitSel + } + + val shiftMOSI = ShiftRegisters(qspi.mosi, 3) + + when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳 //第一个byte + exReg := 0.U + } .elsewhen( isSckPosedgeNext(1) & ~shiftCSn(2) & bitSel.andR ){ //CS为低,且SCK上跳补一拍 的第0bit + when( byteSel === 0.U || byteSel === 1.U ){ //第1、2byte + exReg := 0.U + } .otherwise{ + when( isSpiWrite ){ + exReg := 0.U + } .elsewhen( isSpiRead ){ + exReg := io.datar + } .otherwise{ + assert(false.B, "Assert Failed, empty CMD!\n") + } + } + } .elsewhen( isSckPosedge & ~shiftCSn(1) ){ + exReg := Cat( exReg(6 ,4), shiftMOSI(1) ) + } + } - - - - // val shiftCSn_10M = ShiftRegisters(csn, 3, true.B, true.B) - - - // when( isCrcPass ){ - // localUpdate := localUpdate & ~( 1.U << downRegTemp(0)(3,0) ) - // } .elsewhen( ~shiftCSn_10M(2) & shiftCSn_10M(1) ){ - // localUpdate := localUpdate & ~exMask_100M - // } - - - - - // spiRegDown.io.enw := io.lvdsSlv.downstream_rx_data_valid & (downCnt =/= 0.U | downCnt =/= 1.U) - // spiRegDown.io.dataw := io.lvdsSlv.downstream_rx_data_out - // spiRegDown.io.addrw := Cat( downRegTemp(0)(3,0), downCnt(4,0)) - - // spiRegUp.io.enr := io.lvdsSlv.upstream_tx_data_ready - // spiRegUp.io.addrr := Cat( statusPage, upCnt(4,0)+1.U ) - - - // io.lvdsSlv.upstream_tx_data_in := - // Mux(upCnt === 0.U | upCnt === 1.U | statusPage === 15.U, upReg(upCnt), spiRegUp.io.datar) - - // val int = RegInit(false.B); interrupt := int - // when( int ){ - // int := false.B - // } .elsewhen( RegNext(io.lvdsSlv.upstream_tx_data_ready, false.B) & ~io.lvdsSlv.upstream_tx_data_ready ){ - // int := true.B - // } -