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 // }