Files
eb001/src/main/scala/backBoard/shin/ShinMst.scala.bk

329 lines
11 KiB
Plaintext
Raw Normal View History

2024-10-09 17:37:15 +08:00
package BACK
import chisel3._
import chisel3.util._
2024-10-09 17:37:15 +08:00
class Header_Info_Bundle extends Bundle{
val length = UInt(12.W) // nlength * 8bits
val operator = UInt(4.W)
2024-10-09 17:37:15 +08:00
val param = Vec(3, UInt(16.W))
def init = operator === 0.U
def sync = operator === 1.U
def boardCast = operator === 2.U
def uniCast = operator === 3.U
}
// class FSMC_Port_Bundle extends Bundle{
// val ADIn = Input(UInt(16.W))
// val ADOut = Output(UInt(16.W))
// val ADOEn = Output(Bool())
// val csn = Input(Bool())
// val rdn = Input(Bool())
// val wrn = Input(Bool())
// val advn = Input(Bool())
// }
class ShinMstIO_Bundle extends Bundle{
val FSMC = new FSMC_Port_Bundle
val interrupt = Output(Bool())
val testIO = Input(Bool())
val serOut = Output(Bool())
val serIn = Input(Bool())
val overCLK = Input(Bool())
}
2024-10-09 17:37:15 +08:00
abstract class ShinMstPhyBase extends Module{
val io: ShinMstIO_Bundle = IO(new ShinMstIO_Bundle)
2024-10-09 17:37:15 +08:00
val mirrorDown = Module(new MirrorSRAMDP())
val mirrorUp = Module(new MirrorSRAMDP())
val mirrorReg = Module(new MirrorSRAMDP())
2024-10-09 17:37:15 +08:00
2024-10-22 12:01:37 +08:00
val cdrOut = Module(new CDROut with chisel3.util.experimental.InlineInstance)
val cdrIn = Module(new CDRIn with chisel3.util.experimental.InlineInstance)
2024-10-09 17:37:15 +08:00
io.serOut := cdrOut.io.serDat
cdrIn.io.serDat := io.serIn
cdrIn.io.overCLK := io.overCLK
2024-10-09 17:37:15 +08:00
mirrorDown.io.clockA := clock.asBool
mirrorDown.io.clockB := clock.asBool
mirrorUp.io.clockA := clock.asBool
mirrorUp.io.clockB := clock.asBool
2024-10-16 10:49:06 +08:00
mirrorReg.io.clockA := clock.asBool
mirrorReg.io.clockB := clock.asBool
mirrorReg.io.addrB := DontCare
mirrorReg.io.datawB := DontCare
mirrorReg.io.enwB := false.B
mirrorReg.io.enrB := false.B
2024-10-09 17:37:15 +08:00
}
trait ShinMstSend{ this: ShinMstPhyBase =>
2024-10-16 10:49:06 +08:00
val headByte = (new Header_Info_Bundle).getWidth/8
2024-10-14 17:45:39 +08:00
require( headByte == 8 )
2024-10-14 17:45:39 +08:00
val testIOShift = ShiftRegisters(io.testIO, headByte/2 + 1, false.B, true.B)
2024-10-22 17:11:56 +08:00
val cdrPendBuf = Module( new Queue( new AXIS_Bundle(8), 1, pipe = true, flow = false ) with chisel3.util.experimental.InlineInstance) //Timing Opt
cdrOut.io.axis <> cdrPendBuf.io.deq
2024-10-24 10:02:24 +08:00
val sendHeader = Wire( new Header_Info_Bundle )
sendHeader.length := 512.U
sendHeader.operator := 0.U
sendHeader.param(0) := 0.U
sendHeader.param(1) := 0.U
sendHeader.param(2) := 0.U
val sendHead = sendHeader.asUInt
2024-10-24 10:02:24 +08:00
/*
2024-10-24 10:02:24 +08:00
val sendHeader = Reg( new Header_Info_Bundle )
val sendHead = sendHeader.asUInt
2024-10-24 10:02:24 +08:00
when( ~testIOShift(0) & io.testIO ){
mirrorReg.io.addrB := 0.U
mirrorReg.io.enrB := true.B
} .elsewhen( ~testIOShift(1) & testIOShift(0) ){
mirrorReg.io.addrB := 1.U
mirrorReg.io.enrB := true.B
2024-10-24 10:02:24 +08:00
sendHeader := Cat( sendHeader.asUInt().tail(16), mirrorReg.io.datarB ).asTypeOf(new Header_Info_Bundle)
} .elsewhen( ~testIOShift(2) & testIOShift(1) ){
mirrorReg.io.addrB := 2.U
mirrorReg.io.enrB := true.B
sendHeader := Cat( sendHeader.asUInt().tail(16), mirrorReg.io.datarB ).asTypeOf(new Header_Info_Bundle)
} .elsewhen( ~testIOShift(3) & testIOShift(2) ){
mirrorReg.io.addrB := 3.U
mirrorReg.io.enrB := true.B
sendHeader := Cat( sendHeader.asUInt().tail(16), mirrorReg.io.datarB ).asTypeOf(new Header_Info_Bundle)
} .elsewhen( ~testIOShift(4) & testIOShift(3) ){
sendHeader := Cat( sendHeader.asUInt().tail(16), mirrorReg.io.datarB ).asTypeOf(new Header_Info_Bundle)
}
*/
val isSendTrig: Bool = ~testIOShift(4) & testIOShift(3)
2024-10-16 10:49:06 +08:00
val isRecvEnd = Wire(Bool())
val isTimeout = Wire(Bool())
2024-10-09 17:37:15 +08:00
val sendStateNext = Wire( UInt(3.W) )
val sendStateCurr = RegNext( sendStateNext, 0.U )
val sendCntNext = Wire( UInt(10.W) )
val sendCntCurr = RegNext(sendCntNext)
2024-10-09 17:37:15 +08:00
sendStateNext := Mux1H(Seq(
(sendStateCurr === 0.U) -> Mux( isSendTrig, 1.U, 0.U ),
2024-10-22 17:11:56 +08:00
(sendStateCurr === 1.U) -> Mux( cdrPendBuf.io.enq.fire & sendCntCurr === (headByte-1).U, 2.U, 1.U ),
(sendStateCurr === 2.U) -> Mux( cdrPendBuf.io.enq.fire & sendCntCurr === (sendHeader.length ) - 1.U, 3.U, 2.U ),
2024-10-09 17:37:15 +08:00
(sendStateCurr === 3.U) -> Mux( isRecvEnd | isTimeout, 0.U, 3.U ),
))
sendCntNext := Mux1H(Seq(
(sendStateCurr === 0.U) -> 0.U,
2024-10-22 17:11:56 +08:00
(sendStateCurr === 1.U) -> Mux(cdrPendBuf.io.enq.fire, Mux( sendStateNext =/= 2.U, sendCntCurr + 1.U, 0.U ), sendCntCurr),
(sendStateCurr === 2.U) -> Mux(cdrPendBuf.io.enq.fire, Mux( sendStateNext =/= 3.U, sendCntCurr + 1.U, 0.U ), sendCntCurr),
))
2024-10-09 17:37:15 +08:00
2024-10-22 17:11:56 +08:00
cdrPendBuf.io.enq.valid := sendStateCurr === 1.U | sendStateCurr === 2.U
cdrPendBuf.io.enq.bits.tdata :=
2024-10-09 17:37:15 +08:00
Mux1H(Seq(
( sendStateCurr === 1.U ) -> (sendHead << (sendCntCurr << 3)).apply(63,56),
( sendStateCurr === 2.U ) -> Mux( sendCntCurr.extract(0), mirrorDown.io.datarB(7,0), mirrorDown.io.datarB(15,8) ),
2024-10-09 17:37:15 +08:00
))
2024-10-22 17:11:56 +08:00
cdrPendBuf.io.enq.bits.tlast := sendStateCurr === 2.U & sendCntCurr === (sendHeader.length - 1.U )
cdrPendBuf.io.enq.bits.tuser := false.B
2024-10-09 17:37:15 +08:00
mirrorDown.io.enwB := false.B
mirrorDown.io.datawB := 0.U
mirrorDown.io.enrB := sendStateNext === 2.U
mirrorDown.io.addrB := sendCntNext >> 1
2024-10-09 17:37:15 +08:00
}
trait ShinMstRecv{ this: ShinMstPhyBase =>
2024-10-22 12:01:37 +08:00
val headByte: Int
def isSendTrig: Bool
2024-10-22 12:01:37 +08:00
val RecvStateIdle = 0.U
val RecvStateArm = 1.U
val RecvStateHead = 2.U
val RecvStatePayLoad = 3.U
val RecvStateCRC = 4.U
val RecvStateDeArm = 5.U
val recvStateNext = Wire( UInt(3.W) )
val recvStateCurr = RegNext( recvStateNext, 0.U )
2024-10-22 12:01:37 +08:00
val upPendBuf= Module( new Queue( new AXIS_Bundle(8), 2, pipe = true, flow = false ) with chisel3.util.experimental.InlineInstance )
cdrIn.io.axis <> upPendBuf.io.enq
2024-10-15 17:45:42 +08:00
val recvHeader = Reg( UInt( (new Header_Info_Bundle).getWidth.W) )
val recvCnt = Reg(UInt(10.W))
val recvLength = RegEnable(recvHeader(15,4), upPendBuf.io.deq.fire & ( recvStateCurr === RecvStateHead ) & recvCnt === 3.U)
2024-10-16 10:49:06 +08:00
val isRecvEnd: Bool
2024-10-22 12:01:37 +08:00
isRecvEnd := recvStateCurr === RecvStateDeArm
io.interrupt := recvStateCurr === RecvStateDeArm
2024-10-15 17:45:42 +08:00
recvStateNext := Mux1H(Seq(
2024-10-22 12:01:37 +08:00
(recvStateCurr === RecvStateIdle) -> Mux( isSendTrig, RecvStateArm, RecvStateIdle ), //IDLE
(recvStateCurr === RecvStateArm) -> Mux( upPendBuf.io.deq.valid, RecvStateHead, RecvStateArm ), //Arm
(recvStateCurr === RecvStateHead) -> Mux( upPendBuf.io.deq.fire, Mux( ~upPendBuf.io.deq.bits.tlast, Mux( recvCnt === (headByte).U, RecvStatePayLoad, RecvStateHead ), RecvStateDeArm ), RecvStateHead ), //Header
(recvStateCurr === RecvStatePayLoad) -> Mux( upPendBuf.io.deq.fire, Mux( ~upPendBuf.io.deq.bits.tlast, Mux( recvCnt === (recvLength), RecvStateCRC, RecvStatePayLoad ), RecvStateDeArm ), RecvStatePayLoad ), //payload
2024-10-22 12:01:37 +08:00
(recvStateCurr === RecvStateCRC) -> Mux( upPendBuf.io.deq.fire & upPendBuf.io.deq.bits.tlast, RecvStateDeArm, RecvStateCRC ),//crc
(recvStateCurr === RecvStateDeArm) -> RecvStateIdle,//de-arm
))
2024-10-22 12:01:37 +08:00
when( recvStateCurr =/= recvStateNext ){
recvCnt := 1.U
2024-10-22 12:01:37 +08:00
} .elsewhen( upPendBuf.io.deq.fire ){
recvCnt := recvCnt + 1.U
}
2024-10-22 12:01:37 +08:00
when( upPendBuf.io.deq.fire & ( recvStateCurr === RecvStateHead )) {
recvHeader := Cat( recvHeader.tail(8), upPendBuf.io.deq.bits.tdata )
}
2024-10-22 12:01:37 +08:00
upPendBuf.io.deq.ready :=
recvStateCurr === RecvStateHead | recvStateCurr === RecvStatePayLoad | recvStateCurr === RecvStateCRC
val isRecvError = RegInit(false.B)
when( recvStateCurr === RecvStateIdle & recvStateNext === RecvStateArm ){
isRecvError := false.B
} .elsewhen( upPendBuf.io.deq.fire & upPendBuf.io.deq.bits.tuser ){
isRecvError := true.B
printf("Warning, Wrong Package Received in ShinMst, That could not happened!\n")
} .elsewhen( recvStateCurr === RecvStateHead & recvStateNext === RecvStateDeArm ){
isRecvError := true.B
printf("Warning, Wrong Package Received in ShinMst, That could not happened!\n")
} .elsewhen( recvStateCurr === RecvStatePayLoad & recvStateNext === RecvStateDeArm ){
isRecvError := true.B
printf("Warning, Wrong Package Received in ShinMst, That could not happened!\n")
} .elsewhen( recvStateCurr === RecvStateCRC & upPendBuf.io.deq.fire & upPendBuf.io.deq.bits.tlast & recvCnt =/= 4.U ){
2024-10-22 12:01:37 +08:00
isRecvError := true.B
printf("Warning, Wrong Package Received in ShinMst, That could not happened!\n")
}
2024-10-22 12:01:37 +08:00
2024-10-22 12:01:37 +08:00
val recvDataLatch = RegEnable( upPendBuf.io.deq.bits.tdata, upPendBuf.io.deq.fire & recvStateCurr === 3.U & recvCnt.extract(0) )
mirrorUp.io.enrB := false.B
2024-10-22 12:01:37 +08:00
mirrorUp.io.enwB := upPendBuf.io.deq.fire & recvStateCurr === 3.U & ~recvCnt.extract(0)
mirrorUp.io.datawB := Cat( upPendBuf.io.deq.bits.tdata, recvDataLatch )
mirrorUp.io.addrB := recvCnt >> 1
val recvRamAddr = Reg(UInt(8.W))
when( recvStateCurr === 2.U ){
recvRamAddr := 0.U
} .elsewhen( recvStateCurr === 3.U & recvRamAddr =/= 4.U ){
recvRamAddr := recvRamAddr + 1.U
}
mirrorReg.io.datawB := Mux1H(Seq(
(recvStateCurr === 3.U & recvRamAddr === 0.U) -> (recvHeader >> 16*3),
(recvStateCurr === 3.U & recvRamAddr === 1.U) -> (recvHeader >> 16*2),
(recvStateCurr === 3.U & recvRamAddr === 2.U) -> (recvHeader >> 16*1),
(recvStateCurr === 3.U & recvRamAddr === 3.U) -> (recvHeader >> 16*0),
))
when( recvStateCurr === 3.U & recvRamAddr =/= 4.U ){
mirrorReg.io.addrB := recvRamAddr
mirrorReg.io.enwB := true.B
}
2024-10-16 10:49:06 +08:00
val isTimeout: Bool
isTimeout :=
2024-10-22 12:01:37 +08:00
Counter( Range(0, 20000000), enable = recvStateCurr === 1.U | recvStateCurr === 2.U | recvStateCurr === 3.U, reset = recvStateCurr === 0.U | recvStateCurr === 5.U )._2
2024-10-09 17:37:15 +08:00
}
abstract class ShinMstLinkBase extends ShinMstPhyBase
with ShinMstSend
with ShinMstRecv
trait ShinMstInterface{ this: ShinMstLinkBase =>
2024-10-09 17:37:15 +08:00
io.FSMC.ADOEn := ~io.FSMC.rdn & ~io.FSMC.csn & io.FSMC.advn
2024-10-09 17:37:15 +08:00
val latchAddr = RegEnable( io.FSMC.ADIn, ~io.FSMC.advn & ~io.FSMC.csn)
2024-10-09 17:37:15 +08:00
val isAccessSRAM = ~latchAddr.extract(11)
val isAccessReg = latchAddr.extract(11)
val isAccessDown = ~latchAddr.extract(10)
val activeAddr = latchAddr(9,0)
2024-10-09 17:37:15 +08:00
mirrorDown.io.addrA := activeAddr
mirrorDown.io.datawA := io.FSMC.ADIn
mirrorDown.io.enwA := isAccessSRAM & ~io.FSMC.csn & ~io.FSMC.wrn & isAccessDown
mirrorDown.io.enrA := isAccessSRAM & ~io.FSMC.csn & ~io.FSMC.rdn & isAccessDown
2024-10-09 17:37:15 +08:00
mirrorUp.io.addrA := activeAddr
mirrorUp.io.datawA := io.FSMC.ADIn
mirrorUp.io.enwA := isAccessSRAM & ~io.FSMC.csn & ~io.FSMC.wrn & ~isAccessDown
mirrorUp.io.enrA := isAccessSRAM & ~io.FSMC.csn & ~io.FSMC.rdn & ~isAccessDown
2024-10-09 17:37:15 +08:00
mirrorReg.io.addrA := activeAddr
mirrorReg.io.datawA := io.FSMC.ADIn
mirrorReg.io.enwA := isAccessReg & ~io.FSMC.csn & ~io.FSMC.wrn
mirrorReg.io.enrA := isAccessReg & ~io.FSMC.csn & ~io.FSMC.rdn
2024-10-09 17:37:15 +08:00
io.FSMC.ADOut := Mux( isAccessReg, mirrorReg.io.datarA, Mux( isAccessDown, mirrorDown.io.datarA, mirrorUp.io.datarA) )
2024-10-09 17:37:15 +08:00
}
class ShinMst extends ShinMstLinkBase
with ShinMstInterface