From 605f78c44591e3c0cb50e603fc794af9ea31fb3f Mon Sep 17 00:00:00 2001 From: Ruige Lee Date: Thu, 8 May 2025 17:43:10 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A6=96=E5=85=88=E6=90=AD=E5=BB=BAspi?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=EF=BC=88=E6=9C=AA=E7=BC=96=E8=AF=91=EF=BC=89?= =?UTF-8?q?=EF=BC=8C=E9=87=87=E6=A0=B7=E6=97=B6=E9=92=9F=E4=B8=8E=E4=B8=BB?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=97=B6=E9=92=9F=E5=90=8C=E6=AD=A5=EF=BC=8C?= =?UTF-8?q?=E5=BD=B1=E5=93=8DSPI=20sck=E6=9C=80=E9=AB=98=E9=A2=91=E7=8E=87?= =?UTF-8?q?=EF=BC=8C=E6=B3=A8=E6=84=8F=E8=BE=85=E5=8A=A9=E6=8B=8D=E7=9A=84?= =?UTF-8?q?=E5=BD=B1=E5=93=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/scala/backBoard/shin/Interface.scala | 271 +++++++++--------- .../scala/backBoard/shin/SpiInterface.scala | 157 ++++++++++ 2 files changed, 292 insertions(+), 136 deletions(-) create mode 100644 src/main/scala/backBoard/shin/SpiInterface.scala diff --git a/src/main/scala/backBoard/shin/Interface.scala b/src/main/scala/backBoard/shin/Interface.scala index 7dd5edc..1c85356 100644 --- a/src/main/scala/backBoard/shin/Interface.scala +++ b/src/main/scala/backBoard/shin/Interface.scala @@ -1,154 +1,153 @@ -// package BACK +package BACK -// import chisel3._ -// import chisel3.util._ +import chisel3._ +import chisel3.util._ + +class CommonRegisterBundle extends Bundle{ + val isMstNSlv = Bool() + val hwVersion = UInt(8.W) + val hwSerial = UInt(48.W) + val busRate = UInt(16.W) + + val spiSel = UInt(2.W) + + val isSoftReset = Bool() + val encryptKey = UInt(128.W) + val isEncrypt = Bool() + + val upRecErrorCnt = UInt(32.W) + val downRecErrorCnt = UInt(32.W) + val upForwardErrorCnt = UInt(32.W) + val downForwardErrorCnt = UInt(32.W) + + val qspiErrorCnt = UInt(32.W) + val forwardCnt = UInt(32.W) + val recByteCnt = UInt(32.W) + val forwardByteCnt = UInt(32.W) + + + val wdtStatus = UInt(16.W) + val wdtOverflow = UInt(8.W) + + val timeStamp = UInt(64.W) + val deltaTime = UInt(32.W) + + val linkStatus = UInt(8.W) + +} + +class MasterRegisterBundle extends Bundle{ + + val isExInfoInit = Bool() + val isTxReq = UInt(8.W) + val txStatus = UInt(16.W) + + + val intEnable = UInt(8.W) + val intMask = UInt(8.W) + val intStatus = UInt(8.W) + +} + + +class SlaveRegisterBundle extends Bundle{ + + val RAMSize = UInt(8.W) + val MMUNum = UInt(8.W) + + val nodeSeqAddr = UInt(16.W) + val nodeSetAddr = UInt(16.W) + + + val ebmmu = Vec(8, new Bundle{ + val logicAddr = UInt(32.W) + val length = UInt(16.W) + val phyAddr = UInt(32.W) + val op = UInt(2.W) + val enable = Bool() + }) + + val intStatus = UInt(16.W) + val mb = Vec(8, new Bundle{ + val ctrl = UInt(8.W) + val status = UInt(8.W) + }) + + + val downTimeStamp = UInt(64.W) //下行本地时间戳寄存器 + val upTimeStamp = UInt(64.W) //上行本地时间戳寄存器 + val mstTimeStamp = UInt(64.W) //主站时间戳 + + val dcSyncEnable = Bool() + val dcSyncWidth = UInt(16.W) +} -// class MasterRegisterBundle extends Bundle{ -// val isMstNSlv = Bool() -// val hwVersion = UInt(8.W) -// val hwSerial = UInt(48.W) -// val busRate = UInt(16.W) +class InterfaceIO extends Bundle{ + val ospi = new SPIInterfaceIO -// val isExInfoInit = Bool() -// val isTxReq = UInt(8.W) -// val txStatus = UInt(16.W) -// val spiSel = UInt(2.W) + // val req = Valid(new Bundle{ + // val addr = UInt(16.W) + // val dataw = UInt(8.W) + // val isWRn = Bool() + // }) -// val isSoftReset = Bool() -// val encryptKey = UInt(128.W) -// val isEncrypt = Bool() - -// val intEnable = UInt(8.W) -// val intMask = UInt(8.W) -// val intStatus = UInt(8.W) - -// val upRecErrorCnt = UInt(32.W) -// val downRecErrorCnt = UInt(32.W) - -// val upForwardErrorCnt = UInt(32.W) -// val downForwardErrorCnt = UInt(32.W) - -// val qspiErrorCnt = UInt(32.W) -// val forwardCnt = UInt(32.W) -// val recByteCnt = UInt(32.W) -// val forwardByteCnt = UInt(32.W) - -// val linkStatus = UInt(8.W) - -// val wdtStatus = UInt(16.W) -// val wdtOverflow = UInt(8.W) - -// val timeStamp = UInt(64.W) -// val deltaTime = UInt(32.W) -// } + // val resp = Valid(new Bundle{ + // datar = UInt(8.W) + // }) +} -// class SlaveRegisterBundle extends Bundle{ -// val isMstNSlv = Bool() -// val hwVersion = UInt(8.W) -// val hwSerial = UInt(48.W) -// val busRate = UInt(16.W) +abstract class InterfaceBase extends Module{ + val io: InterfaceIO = IO(new InterfaceIO) -// val RAMSize = UInt(8.W) -// val MMUNum = UInt(8.W) - -// val nodeSeqAddr = UInt(16.W) -// val nodeSetAddr = UInt(16.W) - -// val spiSel = UInt(2.W) - -// val isSoftReset = Bool() -// val encryptKey = UInt(128.W) -// val isEncrypt = Bool() - -// val ebmmu = Vec(8, new Bundle{ -// val logicAddr = UInt(32.W) -// val length = UInt(16.W) -// val phyAddr = UInt(32.W) -// val op = UInt(2.W) -// val enable = Bool() -// }) - -// val intStatus = UInt(16.W) -// val mb = Vec(8, new Bundle{ -// val ctrl = UInt(8.W) -// val status = UInt(8.W) -// }) - -// val upRecErrorCnt = UInt(32.W) -// val downRecErrorCnt = UInt(32.W) - -// val upForwardErrorCnt = UInt(32.W) -// val downForwardErrorCnt = UInt(32.W) - -// val qspiErrorCnt = UInt(32.W) -// val forwardCnt = UInt(32.W) -// val recByteCnt = UInt(32.W) -// val forwardByteCnt = UInt(32.W) - -// val linkStatus = UInt(8.W) - -// val wdtStatus = UInt(16.W) -// val wdtOverflow = UInt(8.W) - -// val timeStamp = UInt(64.W) -// val downTimeStamp = UInt(64.W) //下行本地时间戳寄存器 -// val upTimeStamp = UInt(64.W) //上行本地时间戳寄存器 -// val mstTimeStamp = UInt(64.W) //主站时间戳 -// val deltaTime = UInt(32.W) - -// val dcSyncEnable = Bool() -// val dcSyncWidth = UInt(16.W) -// } - -// class SPIInterfaceIO extends Bundle{ -// val sck = Input(Bool()) -// val csn = Input(Bool()) -// val mosi = Input(Bool()) -// val miso = Output(Bool()) -// } - -// class InterfaceIO extends Bundle{ -// val spi = new SPIInterfaceIO - -// val req = Valid(new Bundle{ -// val addr = UInt(16.W) -// val dataw = UInt(8.W) -// val isWRn = Bool() -// }) - -// val resp = Valid(new Bundle{ -// datar = UInt(8.W) -// }) -// } + val oSpi = Module(new SpiInterface) + io.ospi <> oSpi.io.spi -// abstract class InterfaceBase extends Module{ -// val io: InterfaceIO = IO(new InterfaceIO) + val cReg = Wire(new CommonRegisterBundle) + val mReg = Wire(new MasterRegisterBundle) + val sReg = Wire(new SlaveRegisterBundle) + + def AcquireReg(addr: UInt): UInt = { + Mux1H(Seq( + + )) + } + + def UpdateReg( addr: UInt ) = { + + } + + +} + +trait InterfaceMCUop{ this: InterfaceBase => + oSpi.io.addrSel = Output(UInt(16.W)) + oSpi.io.dataw = Output( UInt(8.W) ) + oSpi.io.datar := RegEnable( AcquireReg(addr = oSpi.io.addrSel), 0.U, oSpi.io.isEnR ) + oSpi.io.isEnW = Output(Bool()) + +} + +trait InterfaceCheckSM{ this: InterfaceBase => + when( oSpi.io.isEnR & oSpi.io.addrSel === ){ + + } +} + +trait InterfaceLVDSop{ this: InterfaceBase => + +} +class Interface extends InterfaceBase +with InterfaceMCUop +{ - - - -// // val softReset = Reg(Bool()) -// // val logicAddr = Reg(UInt(30.W)) -// // val logicLength = Reg(UInt(16.W)) -// // val phyAddr - Reg(UInt(16.W)) - - -// } - - - - - -// class Interface extends InterfaceBase{ - -// } \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/scala/backBoard/shin/SpiInterface.scala b/src/main/scala/backBoard/shin/SpiInterface.scala new file mode 100644 index 0000000..cd4b74f --- /dev/null +++ b/src/main/scala/backBoard/shin/SpiInterface.scala @@ -0,0 +1,157 @@ +package BACK + +import chisel3._ +import chisel3.util._ + +class SPIInterfaceIO extends Bundle{ + val sck = Input(Bool()) + val mosi = Input(Bool()) + val miso = Output(Bool()) + val csn = Input(Bool()) +} + + +class SpiInterface 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) ) + val isEnW = Output(Bool()) + 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 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) + val isSckPosedgeNext = ShiftRegisters(isSckPosedge, 2, false.B, true.B) + + + 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)) + + val isSpiWrite = spiCmd === 0.U + val isSpiRead = spiCmd === 1.U + + val bitSel = Reg(UInt(3.W)) + val byteSel = Reg(UInt(5.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) & isSpiRead + io.isEnW := isSckPosedgeNext(1) & ~shiftCSn(1+1) & bitSel === 0.U & isSpiWrite + 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 ){ + byteSel := byteSel + 1.U + } + } + + when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳 + addrSel := 0.U + } .elsewhen( isSckPosedge & ~shiftCSn(1) ){ + when( byteSel === 0.U || byteSel === 1.U) { //CS为低,且SCK上跳的第0byte + addrSel := Cat( addrSel(14,0), shiftMOSI(1) ) + } .otherwise{ // byteSel > 1.U + addrSel := addrSel + 1.U + } + } + + when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳 + spiCmd := "hFF".U + } .elsewhen( isSckPosedge & ~shiftCSn(1) & byteSel === 2.U ){ //CS为低,且SCK上跳的第0byte + spiCmd := Cat( spiCmd(6,0), shiftMOSI(1) ) + } + + when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳 //第一个byte + exReg := 0.U + } .elsewhen( isSckPosedgeNext(1) & ~shiftCSn(1) & bitSel === 0.U ){ //CS为低,且SCK上跳补一拍 的第0bit + when( byteSel === 1.U || byteSel === 2.U ){ //第1、2byte + exReg := 0.U + } .otherwise{ + when( isSpiWrite ){ + exReg := 0.U + } .elsewhen( isSpiRead ){ + exReg := io.datar + } .otherwise{ + printf("Warning, empty CMD!\n") + } + } + } .elsewhen( isSckPosedge & ~shiftCSn(1) ){ + exReg := Cat( exReg(6 ,0), 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 + // } +