Files
eb001/src/main/scala/backBoard/shin/SpiInterface.scala
2025-05-28 19:12:37 +08:00

208 lines
5.4 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._
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())
val csn = Input(Bool())
}
class RegAccessInterfaceIO extends Bundle{
val addrw = Output(UInt(16.W))
val addrr = Output(UInt(16.W))
val dataw = Output( UInt(8.W) )
val datar = Input( UInt(8.W) )
val isEnW = Output(Bool())
val isEnR = Output(Bool())
}
abstract class SpiInterfaceBase extends Module{
val io = IO(new RegAccessInterfaceIO)
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 isSckPosedge = ~shiftSCK(2) & shiftSCK(1)
val isSckPosedgeNext = ShiftRegisters(isSckPosedge, 2, false.B, true.B)
val isSckNegedge = shiftSCK(2) & ~shiftSCK(1) //确定下降沿放数据到数据线上
val exRego = Reg(UInt(8.W))
val exRegi = Reg(UInt(8.W))
val addrw = RegInit(0.U(16.W))
val addrr = RegInit(0.U(16.W))
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(12.W))
io.isEnR :=
(isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel === 0.U & exRegi === 1.U & byteSel === 3.U ) |
(isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel === 0.U & isSpiRead & byteSel >= 4.U)
io.isEnW := isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel === 0.U & isSpiWrite & byteSel >= 4.U
io.dataw := exRegi
io.addrr := Mux( isSpiRead, addrr + 1.U, addrr )
io.addrw := addrw
// io.addrSel :=
// Mux( isSpiRead, addrSel + 1.U, addrSel )//覆盖三种情况
// val readData = RegEnable(io.datar, io.isEnR)
when( shiftCSn(2) & ~shiftCSn(1) ){
byteSel := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
when( bitSel.andR ){
byteSel := byteSel + 1.U
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrw := 0.U
} .elsewhen(isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel === 0.U & byteSel === 1.U){ //CS为低且SCK上跳的第0byte
addrw := exRegi
} .elsewhen(isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel === 0.U & byteSel === 2.U) {//CS为低且SCK上跳的第0byte
addrw := Cat(addrw(7,0), exRegi)
} .otherwise{ // byteSel > 1.U
when( isSckPosedgeNext(1) & byteSel > 3.U & bitSel === 0.U ){
addrw := addrw + 1.U
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrr := 0.U
} .elsewhen(isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel === 0.U & byteSel === 1.U){ //CS为低且SCK上跳的第0byte
addrr := exRegi
} .elsewhen(isSckPosedgeNext(0) & ~shiftCSn(1) & bitSel === 0.U & byteSel === 2.U) {//CS为低且SCK上跳的第0byte
addrr := Cat(addrr(7,0), exRegi)
} .otherwise{ // byteSel > 1.U
when( isSckPosedgeNext(1) & byteSel > 3.U & bitSel === 0.U ){
addrr := addrr + 1.U
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
spiCmd := "hFF".U
} .elsewhen( isSckPosedgeNext(0) & ~shiftCSn(1) & byteSel === 3.U & bitSel === 0.U ){ //CS为低且SCK上跳的第0byte
spiCmd := exRegi
}
}
class SSpiInterface extends SpiInterfaceBase{
val spi = IO(new SSPIInterfaceIO)
sck := spi.sck
csn := spi.csn
spi.miso := exRego.extract(7)
when( shiftCSn(2) & ~shiftCSn(1) ){
bitSel := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
bitSel := bitSel + 1.U
}
val shiftMOSI = ShiftRegisters(spi.mosi, 3)
//输入看SCK上升沿
when( isSckPosedge & ~shiftCSn(1) ){
when( bitSel === 0.U ){
exRegi := Cat( 0.U, shiftMOSI(1) )
}.otherwise{
exRegi := Cat( exRegi(6 ,0), shiftMOSI(1) )
}
}
//输出在SCK下降沿准备数据
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
exRego := 0.U //第一个byte 地址0
} .elsewhen( isSckNegedge & ~shiftCSn(1) ){
when( bitSel === 0.U ){
when((byteSel === 1.U || byteSel === 2.U) ){
exRego := 0.U //地址1cmd
} .elsewhen( isSpiRead ){
exRego := io.datar
}
}.otherwise{
exRego := exRego << 1
}
}
}
class QSpiInterface extends SpiInterfaceBase{
val qspi = IO(new QSPIInterfaceIO)
sck := qspi.sck
csn := qspi.csn
qspi.miso := exRego(7, 4)
qspi.isDirIn := ~isSpiRead
when( shiftCSn(2) & ~shiftCSn(1) ){
bitSel := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
bitSel := ~bitSel
}
val shiftMOSI = ShiftRegisters(qspi.mosi, 3)
//输入看SCK上升沿
when( isSckPosedge & ~shiftCSn(1) ){
when( bitSel === 0.U ){
exRegi := Cat( 0.U, shiftMOSI(1) )
}.otherwise{
exRegi := Cat( exRegi(3 ,0), shiftMOSI(1) )
}
}
//输出在SCK下降沿准备数据
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
exRego := 0.U //第一个byte 地址0
} .elsewhen( isSckNegedge & ~shiftCSn(1) ){
when( bitSel === 0.U ){
when((byteSel === 1.U || byteSel === 2.U) ){
exRego := 0.U //地址1cmd
} .elsewhen( isSpiRead ){
exRego := io.datar
}
}.otherwise{
exRego := exRego << 4
}
}
}