Files
eb001/src/main/scala/backBoard/shin/Interface.scala

404 lines
11 KiB
Scala
Raw Normal View History

package BACK
2025-04-02 16:40:25 +08:00
import chisel3._
import chisel3.util._
2025-04-02 16:40:25 +08:00
class CommonRegisterBundle extends Bundle{
2025-05-09 16:11:18 +08:00
val mstOrSlv = UInt(2.W)
2025-05-15 14:57:58 +08:00
def modeSel:Bool = mstOrSlv === "h1".U
val hwVersion = UInt(8.W)
val hwSerial = UInt(48.W)
val busRate = UInt(16.W)
2025-04-02 16:40:25 +08:00
2025-05-13 18:03:22 +08:00
val spiSel = UInt(2.W)
2025-04-02 16:40:25 +08:00
2025-05-09 16:11:18 +08:00
// val isSoftReset = Bool()
val encryptKey = UInt(128.W)
// val isEncrypt = Bool()
2025-05-09 16:11:18 +08:00
// val upRecErrorCnt = UInt(32.W)
// val downRecErrorCnt = UInt(32.W)
// val upForwardErrorCnt = UInt(32.W)
// val downForwardErrorCnt = UInt(32.W)
2025-05-09 16:11:18 +08:00
// val qspiErrorCnt = UInt(32.W)
// val forwardCnt = UInt(32.W)
// val recByteCnt = UInt(32.W)
// val forwardByteCnt = UInt(32.W)
2025-05-09 16:11:18 +08:00
// val wdtStatus = UInt(16.W)
// val wdtOverflow = UInt(8.W)
val timeStamp = UInt(64.W)
2025-05-15 14:57:58 +08:00
val mstDeltaTime = UInt(32.W)
// val linkStatus = UInt(8.W)
2025-05-09 16:11:18 +08:00
val smEnqAddr = Vec(8, UInt(11.W)) //触发SM切换缓冲区的地址 (或读或写)
val smDeqAddr = Vec(8, UInt(11.W)) //触发SM切换缓冲区的地址 (或读或写)
}
class MasterRegisterBundle extends Bundle{
2025-05-09 16:11:18 +08:00
val txSM = UInt(2.W)
val rxSM = UInt(2.W)
val txLength = UInt(12.W)
// val txStatus = UInt(16.W)
2025-05-15 14:57:58 +08:00
val rplTimeStampTx = UInt(16.W)
// val intEnable = UInt(8.W)
// val intMask = UInt(8.W)
// val intStatus = UInt(8.W)
2025-04-24 16:18:33 +08:00
}
2025-04-24 16:18:33 +08:00
class SlaveRegisterBundle extends Bundle{
2025-04-24 16:18:33 +08:00
// val RAMSize = UInt(8.W)
// val MMUNum = UInt(8.W)
2025-04-24 16:18:33 +08:00
// val nodeSeqAddr = UInt(16.W)
// val nodeSetAddr = UInt(16.W)
2025-04-24 16:18:33 +08:00
// 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()
// })
2025-04-24 16:18:33 +08:00
// val intStatus = UInt(16.W)
// val mb = Vec(8, new Bundle{
// val ctrl = UInt(8.W)
// val status = UInt(8.W)
// })
2025-04-24 16:18:33 +08:00
// val downTimeStamp = UInt(64.W) //下行本地时间戳寄存器
// val upTimeStamp = UInt(64.W) //上行本地时间戳寄存器
// val mstTimeStamp = UInt(64.W) //主站时间戳
2025-04-24 16:18:33 +08:00
// val dcSyncEnable = Bool()
// val dcSyncWidth = UInt(16.W)
}
2025-04-24 16:18:33 +08:00
class InterfaceIO extends Bundle{
2025-05-13 18:03:22 +08:00
val ospi = new SSPIInterfaceIO
val oqspi = new QSPIInterfaceIO
val iqspi = new QSPIInterfaceIO
2025-04-24 16:18:33 +08:00
2025-05-09 16:11:18 +08:00
2025-05-15 14:57:58 +08:00
// val modeSel = Output(Bool())
2025-05-09 16:11:18 +08:00
val txReq = Valid(new Bundle{
val txSM = UInt(2.W)
val rxSM = UInt(2.W)
val txLength = UInt(12.W)
2025-05-09 16:11:18 +08:00
}) //发送请求和SM代号
val dSMdeq = Output( Vec(4, Bool()) )
val uSMenq = Output( Vec(4, Bool()) )
val sram_w = Flipped(Vec( 4, new SRAM2kWRIO)) //QSPI
val sram_r = Flipped(Vec( 4, new SRAM2kRDIO)) //QSPI
2025-05-15 14:57:58 +08:00
val cReg = Output(new CommonRegisterBundle)
val mReg = Output(new MasterRegisterBundle)
// val sReg = Output(new SlaveRegisterBundle)
2025-05-09 16:11:18 +08:00
2025-05-15 14:57:58 +08:00
// val smEnqAddr = Output(Vec(8, UInt(16.W))) //触发SM切换缓冲区的地址 (或读或写)
// val smDeqAddr = Output(Vec(8, UInt(16.W))) //触发SM切换缓冲区的地址 (或读或写)
val mstDeltaTimeStamp = Input(UInt(32.W))
}
2025-04-24 16:18:33 +08:00
abstract class InterfaceBase extends Module{
val io: InterfaceIO = IO(new InterfaceIO)
2025-05-13 18:03:22 +08:00
val oSpi = Module(new SSpiInterface)
val oQSpi = Module(new QSpiInterface)
val iQSpi = Module(new QSpiInterface)
io.ospi <> oSpi.spi
io.oqspi <> oQSpi.qspi
io.iqspi <> iQSpi.qspi
2025-04-02 16:40:25 +08:00
2025-05-15 14:57:58 +08:00
val cReg = Wire(new CommonRegisterBundle); io.cReg := cReg
val mReg = Wire(new MasterRegisterBundle); io.mReg := mReg
// val sReg = Wire(new SlaveRegisterBundle)
2025-04-02 16:40:25 +08:00
2025-05-15 14:57:58 +08:00
2025-05-09 16:11:18 +08:00
val isSysInit = cReg.mstOrSlv =/= 0.U
val isMstMode = cReg.mstOrSlv === "h1".U
val isSlvMode = cReg.mstOrSlv === "h2".U
2025-04-02 16:40:25 +08:00
2025-05-09 16:11:18 +08:00
def AcquireReg(addr: UInt): UInt = {
Mux1H(
Seq(
(addr === "h0".U) -> cReg.mstOrSlv,
(addr === "h1".U) -> cReg.hwVersion,
) ++
((0 until 6).map{ i =>
(addr === ("h2".U + i.U) ) -> cReg.hwSerial( 8*i+7,8*i+0 )
2025-05-09 16:11:18 +08:00
}) ++
Seq(
(addr === "h8".U ) -> cReg.busRate( 7,0),
(addr === "h9".U ) -> cReg.busRate(15,8),
(addr === "h20".U & isMstMode) -> Cat(mReg.rxSM, mReg.txSM, 0.U(1.W) ),
(addr === "h21".U & isMstMode) -> mReg.txLength,
2025-05-15 14:57:58 +08:00
(addr === "h25".U & isMstMode) -> mReg.rplTimeStampTx(7,0),
(addr === "h26".U & isMstMode) -> mReg.rplTimeStampTx(15,8),
2025-05-13 18:03:22 +08:00
(addr === "h27".U ) -> cReg.spiSel
2025-05-09 16:11:18 +08:00
) ++
2025-05-09 16:11:18 +08:00
((0 until 16).map{ i =>
(addr === ("h80".U + i.U) ) -> cReg.encryptKey( 8*i+7,8*i+0 )
2025-05-09 16:11:18 +08:00
}) ++
2025-05-15 14:57:58 +08:00
Seq(
(addr === "h1c0".U ) -> cReg.timeStamp(7,0),
(addr === "h1c1".U ) -> cReg.timeStamp(15,8),
(addr === "h1c2".U ) -> cReg.timeStamp(23,16),
(addr === "h1c3".U ) -> cReg.timeStamp(31,24),
(addr === "h1c4".U ) -> cReg.timeStamp(39,32),
(addr === "h1c5".U ) -> cReg.timeStamp(47,40),
(addr === "h1c6".U ) -> cReg.timeStamp(55,48),
(addr === "h1c7".U ) -> cReg.timeStamp(63,56),
(addr === "h1D0".U ) -> io.mstDeltaTimeStamp(7,0),
(addr === "h1D1".U ) -> io.mstDeltaTimeStamp(15,8),
(addr === "h1D2".U ) -> io.mstDeltaTimeStamp(23,16),
(addr === "h1D3".U ) -> io.mstDeltaTimeStamp(31,24),
)
2025-05-09 16:11:18 +08:00
)
}
2025-04-02 16:40:25 +08:00
2025-05-09 16:11:18 +08:00
2025-05-09 16:11:18 +08:00
}
2025-04-24 16:18:33 +08:00
trait InterfaceMCUop{ this: InterfaceBase =>
2025-04-24 16:18:33 +08:00
2025-04-16 16:49:42 +08:00
2025-05-13 18:03:22 +08:00
val isEnW = Mux1H(Seq(
( cReg.spiSel === 0.U ) -> iQSpi.io.isEnW,
( cReg.spiSel === 1.U ) -> oSpi.io.isEnW,
( cReg.spiSel === 2.U ) -> oQSpi.io.isEnW,
))
val addrSel = Mux1H(Seq(
( cReg.spiSel === 0.U ) -> iQSpi.io.addrSel,
( cReg.spiSel === 1.U ) -> oSpi.io.addrSel,
( cReg.spiSel === 2.U ) -> oQSpi.io.addrSel,
))
val dataw = Mux1H(Seq(
( cReg.spiSel === 0.U ) -> iQSpi.io.dataw,
( cReg.spiSel === 1.U ) -> oSpi.io.dataw,
( cReg.spiSel === 2.U ) -> oQSpi.io.dataw,
))
val isEnR = Mux1H(Seq(
( cReg.spiSel === 0.U ) -> iQSpi.io.isEnR,
( cReg.spiSel === 1.U ) -> oSpi.io.isEnR,
( cReg.spiSel === 2.U ) -> oQSpi.io.isEnR,
))
val datar = MuxCase( 0.U, Array(
((addrSel & "hFF00".U) === "h0000".U) -> RegEnable( AcquireReg(addr = oSpi.io.addrSel), 0.U, oSpi.io.isEnR ),
((addrSel & "hFF00".U) === "h0800".U) -> io.sram_r(0).datar,
((addrSel & "hFF00".U) === "h1000".U) -> 0.U,
((addrSel & "hFF00".U) === "h1800".U) -> io.sram_r(1).datar,
((addrSel & "hFF00".U) === "h2000".U) -> 0.U,
((addrSel & "hFF00".U) === "h2800".U) -> io.sram_r(2).datar,
((addrSel & "hFF00".U) === "h3000".U) -> 0.U,
((addrSel & "hFF00".U) === "h3800".U) -> io.sram_r(3).datar,
((addrSel & "hFF00".U) === "h4000".U) -> 0.U,
2025-05-09 16:11:18 +08:00
))
2025-05-13 18:03:22 +08:00
iQSpi.io.datar := Mux(cReg.spiSel === 0.U, datar, 0.U)
oSpi.io.datar := Mux(cReg.spiSel === 1.U, datar, 0.U)
oQSpi.io.datar := Mux(cReg.spiSel === 2.U, datar, 0.U)
2025-05-14 16:26:20 +08:00
when( isEnW ){
printf(s"SPI/QSPI Write 0x%x, @0x%x\n", dataw, addrSel)
}
when( isEnR ){
printf(s"SPI/QSPI Readout 0x%x, @0x%x\n", datar, addrSel)
}
2025-05-13 18:03:22 +08:00
2025-05-09 16:11:18 +08:00
cReg.mstOrSlv := RegEnable( dataw(1,0), 0.U, isEnW & addrSel === "h0".U & cReg.mstOrSlv === 0.U )
cReg.hwVersion := RegEnable( dataw , 0.U, isEnW & addrSel === "h1".U & cReg.mstOrSlv === 0.U )
cReg.hwSerial :=
Cat(
(0 until 6).map{ i =>
RegEnable( dataw, 0.U, isEnW & addrSel === ("h2".U + i.U) & cReg.mstOrSlv === 0.U )
}.reverse
)
2025-05-09 16:11:18 +08:00
cReg.busRate :=
Cat(
RegEnable( dataw, 0.U, isEnW & addrSel === "h9".U & cReg.mstOrSlv === 0.U ),
RegEnable( dataw, 0.U, isEnW & addrSel === "h8".U & cReg.mstOrSlv === 0.U )
)
cReg.encryptKey :=
Cat(
(0 until 16).map{ i =>
RegEnable( dataw, 0.U, isEnW & addrSel === ("h80".U + i.U) & cReg.mstOrSlv === 0.U )
}.reverse
2025-05-09 16:11:18 +08:00
)
2025-05-13 18:03:22 +08:00
cReg.spiSel :=
RegEnable( dataw(1,0), 0.U, isEnW & addrSel === "h27".U & cReg.mstOrSlv === 0.U )
2025-05-09 16:11:18 +08:00
mReg.txSM := RegEnable( dataw(2,1), 0.U, isEnW & addrSel === "h20".U )
mReg.rxSM := RegEnable( dataw(4,3), 0.U, isEnW & addrSel === "h20".U )
mReg.txLength := Cat( RegEnable( dataw, 0.U, isEnW & addrSel === "h22".U ), RegEnable( dataw, 0.U, isEnW & addrSel === "h21".U ) )
2025-05-09 16:11:18 +08:00
2025-05-15 14:57:58 +08:00
mReg.rplTimeStampTx :=
Cat(
RegEnable( dataw, 0.U, isEnW & addrSel === "h26".U ),
RegEnable( dataw, 0.U, isEnW & addrSel === "h25".U )
)
2025-05-09 16:11:18 +08:00
}
2025-04-16 16:49:42 +08:00
trait InterfaceCheckSM{ this: InterfaceBase =>
val isEnW: Bool
val addrSel: UInt
val dataw: UInt
val isEnR: Bool
2025-05-09 16:11:18 +08:00
for( i <- 0 until 8 ){
cReg.smEnqAddr(i) :=
Cat(
2025-05-13 11:32:38 +08:00
RegEnable( dataw, 0.U, isEnW & addrSel === ("h201".U + (i*2).U) ),
2025-05-12 15:41:11 +08:00
RegEnable( dataw, 0.U, isEnW & addrSel === ("h200".U + (i*2).U) ),
2025-05-09 16:11:18 +08:00
)
cReg.smDeqAddr(i) :=
Cat(
2025-05-13 11:32:38 +08:00
RegEnable( dataw, 0.U, isEnW & addrSel === ("h301".U + (i*2).U) ),
2025-05-12 15:41:11 +08:00
RegEnable( dataw, 0.U, isEnW & addrSel === ("h300".U + (i*2).U) ),
2025-05-09 16:11:18 +08:00
)
}
2025-05-09 16:11:18 +08:00
io.sram_r(0).addrr := addrSel
io.sram_r(1).addrr := addrSel
io.sram_r(2).addrr := addrSel
io.sram_r(3).addrr := addrSel
io.sram_r(0).enr := isEnR & (( addrSel & "hF800".U ) === "h0800".U)
io.sram_r(1).enr := isEnR & (( addrSel & "hF800".U ) === "h1800".U)
io.sram_r(2).enr := isEnR & (( addrSel & "hF800".U ) === "h2800".U)
io.sram_r(3).enr := isEnR & (( addrSel & "hF800".U ) === "h3800".U)
io.sram_w(0).addrw := addrSel
io.sram_w(1).addrw := addrSel
io.sram_w(2).addrw := addrSel
io.sram_w(3).addrw := addrSel
io.sram_w(0).dataw := dataw
io.sram_w(1).dataw := dataw
io.sram_w(2).dataw := dataw
io.sram_w(3).dataw := dataw
io.sram_w(0).enw := isEnW & (( addrSel & "hF800".U ) === "h1000".U)
io.sram_w(1).enw := isEnW & (( addrSel & "hF800".U ) === "h2000".U)
io.sram_w(2).enw := isEnW & (( addrSel & "hF800".U ) === "h3000".U)
io.sram_w(3).enw := isEnW & (( addrSel & "hF800".U ) === "h4000".U)
io.dSMdeq(0) := isEnR & (( addrSel & "hF800".U ) === "h0800".U) & (addrSel(10,0) === cReg.smDeqAddr(0))
io.dSMdeq(1) := isEnR & (( addrSel & "hF800".U ) === "h0800".U) & (addrSel(10,0) === cReg.smDeqAddr(2))
io.dSMdeq(2) := isEnR & (( addrSel & "hF800".U ) === "h0800".U) & (addrSel(10,0) === cReg.smDeqAddr(4))
io.dSMdeq(3) := isEnR & (( addrSel & "hF800".U ) === "h0800".U) & (addrSel(10,0) === cReg.smDeqAddr(6))
2025-05-09 16:11:18 +08:00
io.uSMenq(0) := isEnW & (( addrSel & "hF800".U ) === "h1000".U) & (addrSel(10,0) === cReg.smEnqAddr(1))
io.uSMenq(1) := isEnW & (( addrSel & "hF800".U ) === "h2000".U) & (addrSel(10,0) === cReg.smEnqAddr(3))
io.uSMenq(2) := isEnW & (( addrSel & "hF800".U ) === "h3000".U) & (addrSel(10,0) === cReg.smEnqAddr(5))
io.uSMenq(3) := isEnW & (( addrSel & "hF800".U ) === "h4000".U) & (addrSel(10,0) === cReg.smEnqAddr(7))
}
2025-04-16 16:49:42 +08:00
trait InterfaceLVDSop{ this: InterfaceBase =>
2025-04-16 16:49:42 +08:00
}
2025-04-16 16:49:42 +08:00
trait InterfaceSync{ this: InterfaceBase =>
cReg.timeStamp := RegNext( cReg.timeStamp + 1.U, 0.U )
2025-04-16 16:49:42 +08:00
2025-05-15 14:57:58 +08:00
cReg.mstDeltaTime := io.mstDeltaTimeStamp
// Cat(
//RegEnable( dataw, 0.U, isEnW & addrSel === "h1d3".U ),
//RegEnable( dataw, 0.U, isEnW & addrSel === "h1d2".U ),
//RegEnable( dataw, 0.U, isEnW & addrSel === "h1d1".U ),
//RegEnable( dataw, 0.U, isEnW & addrSel === "h1d0".U ),
// )
}
2025-04-16 16:49:42 +08:00
class Interface extends InterfaceBase
with InterfaceMCUop
with InterfaceCheckSM
with InterfaceLVDSop
with InterfaceSync
{
2025-05-09 16:11:18 +08:00
io.txReq.bits.txSM := mReg.txSM
io.txReq.bits.rxSM := mReg.rxSM
io.txReq.bits.txLength := mReg.txLength
io.txReq.valid := isEnW & addrSel === "h20".U & dataw.extract(0) === "b1".U //& mReg.txLength =/= 0.U
2025-05-15 14:57:58 +08:00
// io.smEnqAddr := cReg.smEnqAddr
// io.smDeqAddr := cReg.smDeqAddr
2025-05-09 16:11:18 +08:00
}