Files
eb001/src/main/scala/backBoard/SpiSlv.scala

154 lines
4.7 KiB
Scala
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package BACK
import chisel3._
import chisel3.util._
trait BackBoardSpiSlv{ this: BackBoardSlvLocal =>
val sck = Wire(Bool())
val mosi = Wire(Bool())
val csn = Wire(Bool())
val clk100M = Wire(Bool())
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 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 isSckPosedgeNext = withClockAndReset( clk100M.asClock, reset ){ ShiftRegisters(isSckPosedge, 2, false.B, true.B) }
val exReg_100M = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(8.W)) }
val exMask_100M = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(16.W)) }
val cmd_100M = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(8.W)) }
val pageSel = cmd_100M(5,4)
val spiCmd = cmd_100M(3,0)
val bitSel = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(3.W)) }
val byteSel = withClockAndReset( clk100M.asClock, reset ){ 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
withClockAndReset( clk100M.asClock, reset ){//100M
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下跳
bitSel := 0.U
byteSel := 0.U
cmd_100M := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) & byteSel === 0.U ){ //CS为低且SCK上跳的第0byte
cmd_100M := Cat( cmd_100M(6,0), shiftMOSI(1) )
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
exReg_100M := upReg(0)
} .elsewhen( isSckPosedgeNext(1) & ~shiftCSn(1) & bitSel === 0.U ){ //CS为低且SCK上跳补一拍 的第0bit
when( byteSel === 1.U ){
exReg_100M := upReg(1)
} .elsewhen( spiCmd === 2.U & byteSel === 2.U ){
exReg_100M := localUpdate(7,0)
} .elsewhen( spiCmd === 2.U & byteSel === 3.U ){
exReg_100M := localUpdate(15,8)
} .elsewhen( spiCmd === 0.U & (byteSel =/= 0.U | byteSel =/= 1.U) ){
exReg_100M := spiRegDown.io.datar
}
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
exReg_100M := Cat( exReg_100M(6 ,0), shiftMOSI(1) )
}
when( isSckPosedgeNext(1) & ~shiftCSn(1) & byteSel === 3.U & bitSel === 0.U & spiCmd === 3.U ){
exMask_100M := Cat( exReg_100M, exMask_100M(7,0) )
} .elsewhen( isSckPosedgeNext(1) & ~shiftCSn(1) & byteSel === 4.U & bitSel === 0.U & spiCmd === 3.U ){
exMask_100M := Cat( exMask_100M(15,8), exReg_100M )
}
}
}
class SpiSlv extends BackBoardSlvLocal
with BackBoardSlvStatusPR
with BackBoardSpiSlv{
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()))
val interrupt = IO(Output(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)
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
}
}