package BACK import chisel3._ import chisel3.util._ trait BackBoardSpiSlv{ this: BackBoardSlvLocal => def page: Int val sck = Wire(Bool()) val mosi = Wire(Bool()) val csn = Wire(Bool()) val clk100M = Wire(Bool()) val localReg = for( i <- 0 until page ) yield {Reg(Vec(31, UInt(8.W)))} val localUpdate = RegInit(0.U(16.W)) val shiftSCK = withClockAndReset( clk100M.asClock, reset ){ ShiftRegisters(sck, 3, false.B, true.B) } val shiftCSn = withClockAndReset( clk100M.asClock, reset ){ ShiftRegisters(csn, 3, true.B, true.B) } val shiftMOSI = withClockAndReset( clk100M.asClock, reset ){ ShiftRegisters(mosi, 3) } val isSckPosedge = ~shiftSCK(2) & shiftSCK(1) val isSckNegedge = shiftSCK(2) & ~shiftSCK(1) val exReg_100M = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt((8*31).W)) } val cmd_100M = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(8.W)) } val pageSel = cmd_100M(7,4) val spiCmd = cmd_100M(3,0) val localPage = PriorityMux( ( 0 until page ).map{ i => ( i.U === pageSel ) -> localReg(i) } ) val cnt_100M = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(4.W)) } // val misoReg = withClockAndReset( clk100M.asClock, reset ){ Reg(Bool()) } withClockAndReset( clk100M.asClock, reset ){//100M when( shiftCSn(2) & ~shiftCSn(1) ){ cnt_100M := 0.U // misoReg := false.B } .elsewhen( isSckPosedge & ~shiftCSn(1) & cnt_100M < 8.U ){ cmd_100M := Cat( cmd_100M(6,0), shiftMOSI(1) ) cnt_100M := cnt_100M + 1.U } .elsewhen( isSckNegedge & ~shiftCSn(1) & cnt_100M === 8.U ){ exReg_100M := Mux( spiCmd.extract(1), Cat( localUpdate, 0.U((8*29).W) ), Cat( localPage.reverse) ) cnt_100M := cnt_100M + 1.U } .elsewhen( isSckPosedge & ~shiftCSn(1) & cnt_100M === 9.U ){ // misoReg := exReg_100M.extract(exReg_100M.getWidth-1) exReg_100M := Cat( exReg_100M(exReg_100M.getWidth-2 ,0), shiftMOSI(1) ) } } } class SpiSlv extends BackBoardSlvLocal with BackBoardSlvStatusPR with BackBoardSpiSlv{ def page: Int = 1 val spi = IO(new Bundle{ val sck = Input(Bool()) val mosi = Input(Bool()) val miso = Output(Bool()) val csn = Input(Bool()) }) val clk100MIO = IO(Input(Bool())) sck := spi.sck mosi := spi.mosi csn := spi.csn spi.miso := exReg_100M.extract(exReg_100M.getWidth-1) clk100M := clk100MIO val shiftCSn_10M = ShiftRegisters(csn, 3, true.B, true.B) for( i <- 0 until page ){ when( isCrcPass ){ when( downRegTemp(0)(3,0) === i.U ){ localUpdate := localUpdate & ~( 1.U << i ) for( j <- 1 until 32 ) { localReg(i)(j-1) := downRegTemp(j) } } } .elsewhen( ~shiftCSn_10M(2) & shiftCSn_10M(1) & spiCmd === 1.U ){ when( i.U === pageSel ){ for( j <- 0 until 31 ) { localReg(i)(30-j) := exReg_100M(8*j+7,8*j) } } } .elsewhen( ~shiftCSn_10M(2) & shiftCSn_10M(1) & spiCmd === 3.U ){ localUpdate := localUpdate & (~exReg_100M(15,0)) } when( statusPage === i.U ){ for( j <- 1 until 32 ) { upReg(j) := localReg(i)(j-1) } } } }