Merge branch 'mp_eb_dev' into feature/clk3_shift_allow
# Conflicts: # src/main/scala/backBoard/ebus/CDRIn.scala
This commit is contained in:
@@ -8,11 +8,11 @@ import chisel3.util._
|
||||
class CDRInIO extends Bundle{
|
||||
val axis = Decoupled(new AXIS_Bundle(8))
|
||||
val serDat = Input(Bool())
|
||||
|
||||
val flush = Input(Bool())
|
||||
}
|
||||
|
||||
|
||||
abstract class CDRInBase extends Module{
|
||||
abstract class CDRInBase extends Module with RequireAsyncReset{
|
||||
|
||||
|
||||
val io: CDRInIO = IO(new CDRInIO)
|
||||
@@ -21,48 +21,6 @@ abstract class CDRInBase extends Module{
|
||||
val syncSerDat = Wire(Bool())
|
||||
}
|
||||
|
||||
trait CDRInOverSample{ this: CDRInBase =>
|
||||
|
||||
val overCLK = IO(Input(Bool()))
|
||||
val sampleRate: Int = 4
|
||||
require(sampleRate >= 4)
|
||||
|
||||
val sampleReg = withClockAndReset(overCLK.asClock, reset.asBool){ ShiftRegisters( RegNext(io.serDat), sampleRate+3 ) }
|
||||
|
||||
val flitReg = for( i <- 0 until sampleRate ) yield {
|
||||
withClockAndReset(overCLK.asClock, reset.asBool){
|
||||
RegNext(
|
||||
(sampleReg(i) & sampleReg(i+1)) |
|
||||
(sampleReg(i) & sampleReg(i+2)) |
|
||||
(sampleReg(i+1) & sampleReg(i+2)), false.B
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val arbCnt = withClockAndReset(overCLK.asClock, reset.asBool){ RegInit("b00000001".U(sampleRate.W)) }
|
||||
arbCnt := Cat( arbCnt(sampleRate-2,0), arbCnt.extract(sampleRate-1) )
|
||||
val arbLock = withClockAndReset(overCLK.asClock, reset.asBool){ RegInit("b00000001".U(sampleRate.W)) }
|
||||
withClockAndReset(overCLK.asClock, reset.asBool){
|
||||
when( flitReg(0) ^ flitReg(1) ){
|
||||
arbLock := arbCnt
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
val asyncSerDat = withClockAndReset(overCLK.asClock, reset.asBool){ RegNext(
|
||||
Mux1H(
|
||||
(for { i <- 0 until sampleRate; j <- 0 until sampleRate } yield {
|
||||
//跳变沿到来锁定的位置 锁定拍当前所在的位置 选择锁定拍后一拍的值认为是正确值
|
||||
((arbLock === (1.U << i)) & (arbCnt === (1.U << j))) -> flitReg((sampleRate + 2 - i + j) % sampleRate)
|
||||
})
|
||||
)
|
||||
)}
|
||||
|
||||
|
||||
syncSerDat := ShiftRegister( asyncSerDat, 2 )
|
||||
|
||||
}
|
||||
|
||||
trait CDRInMultiSample{ this: CDRInBase =>
|
||||
|
||||
@@ -252,23 +210,34 @@ trait CDRInAxis{ this: CDRInBase =>
|
||||
val bitCnt = Reg(UInt(4.W))
|
||||
val byteCnt = RegInit(0.U((12+1).W))
|
||||
|
||||
val checkSFD = RegInit( 0.U(20.W) ); checkSFD := Cat( checkSFD(18,0), syncSerDat )
|
||||
val checkSFD = RegInit( 0.U(20.W) )
|
||||
|
||||
when( io.flush ){
|
||||
checkSFD := 0.U
|
||||
} .otherwise{
|
||||
checkSFD := Cat( checkSFD(18,0), syncSerDat )
|
||||
}
|
||||
|
||||
val shiftData = Dualb4b5Decoder(checkSFD(9,0))
|
||||
|
||||
val payloadLen = RegInit(0.U(12.W))
|
||||
when( byteCnt === 0.U & bitCnt === 9.U & stateCurr === STATE_HEADER ){
|
||||
|
||||
when( io.flush ){
|
||||
payloadLen := 0.U
|
||||
} .elsewhen( byteCnt === 0.U & bitCnt === 9.U & stateCurr === STATE_HEADER ){
|
||||
payloadLen := Cat( shiftData, 0.U(4.W) )
|
||||
} .elsewhen( byteCnt === 1.U & bitCnt === 9.U & stateCurr === STATE_HEADER ){
|
||||
payloadLen := Cat( payloadLen(11,4), shiftData(7,4) )
|
||||
}
|
||||
|
||||
stateNext :=
|
||||
Mux1H(Seq(
|
||||
(stateCurr === STATE_IDLE) -> ( Mux( checkSFD === Cat(ETH_PRE , ETH_SFD), STATE_HEADER, STATE_IDLE )), //IDLE
|
||||
(stateCurr === STATE_HEADER) -> ( Mux( (byteCnt === (HeaderByte-1).U) & (bitCnt === 9.U), STATE_PAYLOAD, STATE_HEADER ) ),
|
||||
(stateCurr === STATE_PAYLOAD) -> ( Mux( (byteCnt === (payloadLen + (4 - 1).U) ) & (bitCnt === 9.U), STATE_IDLE, STATE_PAYLOAD )), // PAYLOAD
|
||||
)) //crc
|
||||
Mux( io.flush, STATE_IDLE,
|
||||
Mux1H(Seq(
|
||||
(stateCurr === STATE_IDLE) -> ( Mux( checkSFD === Cat(ETH_PRE , ETH_SFD), STATE_HEADER, STATE_IDLE )), //IDLE
|
||||
(stateCurr === STATE_HEADER) -> ( Mux( (byteCnt === (HeaderByte-1).U) & (bitCnt === 9.U), STATE_PAYLOAD, STATE_HEADER ) ),
|
||||
(stateCurr === STATE_PAYLOAD) -> ( Mux( (byteCnt === (payloadLen + (4 - 1).U) ) & (bitCnt === 9.U), STATE_IDLE, STATE_PAYLOAD )), // PAYLOAD
|
||||
)) //crc
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -284,7 +253,9 @@ trait CDRInAxis{ this: CDRInBase =>
|
||||
}
|
||||
}
|
||||
|
||||
when( stateCurr === STATE_IDLE & ( checkSFD === Cat(ETH_PRE, ETH_SFD) ) ){ //first align
|
||||
when( io.flush ){
|
||||
byteCnt := 0.U
|
||||
} .elsewhen( stateCurr === STATE_IDLE & ( checkSFD === Cat(ETH_PRE, ETH_SFD) ) ){ //first align
|
||||
byteCnt := 0.U
|
||||
} .elsewhen( bitCnt === 9.U ){
|
||||
when( stateCurr === STATE_HEADER ){
|
||||
@@ -303,26 +274,29 @@ trait CDRInAxis{ this: CDRInBase =>
|
||||
val axis_valid = RegInit(false.B)
|
||||
val axis_tdata = RegEnable( shiftData, bitCnt === 9.U & ( stateCurr === STATE_HEADER | stateCurr === STATE_PAYLOAD ) )
|
||||
val axis_tuser = false.B
|
||||
val axis_tlast = RegNext( stateCurr === STATE_PAYLOAD & stateNext === STATE_IDLE, false.B )
|
||||
val axis_tlast = RegInit( false.B )
|
||||
|
||||
|
||||
|
||||
io.axis.valid := axis_valid
|
||||
io.axis.bits.tdata := axis_tdata
|
||||
io.axis.bits.tuser := axis_tuser
|
||||
io.axis.bits.tlast := axis_tlast
|
||||
|
||||
|
||||
when( io.axis.fire ){
|
||||
when( io.flush ){
|
||||
axis_valid := false.B
|
||||
} .elsewhen( io.axis.fire ){
|
||||
axis_valid := false.B
|
||||
} .elsewhen( bitCnt === 9.U & ( stateCurr === STATE_HEADER | stateCurr === STATE_PAYLOAD ) ){
|
||||
axis_valid := true.B
|
||||
}
|
||||
|
||||
}
|
||||
when( io.flush ){
|
||||
axis_tlast := false.B
|
||||
} .otherwise{
|
||||
axis_tlast := (stateCurr === STATE_PAYLOAD & stateNext === STATE_IDLE)
|
||||
}
|
||||
|
||||
class CDRIn extends CDRInBase
|
||||
with CDRInAxis
|
||||
with CDRInOverSample{
|
||||
require(false)
|
||||
}
|
||||
|
||||
class MPCDRIn extends CDRInBase
|
||||
|
||||
@@ -14,11 +14,13 @@ class CDROutIO extends Bundle{
|
||||
val axis = Flipped(Decoupled(new AXIS_Bundle(8)))
|
||||
val serDat = Output(Bool())
|
||||
|
||||
val flush = Input(Bool())
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class CDROut extends Module{
|
||||
class CDROut extends Module with RequireAsyncReset{
|
||||
val io: CDROutIO = IO(new CDROutIO)
|
||||
def PRE_NUM = 3 //PRE_NUM should >= 3
|
||||
|
||||
@@ -39,12 +41,14 @@ class CDROut extends Module{
|
||||
|
||||
val shiftData = RegInit(0.U(10.W))
|
||||
|
||||
stateNext := Mux1H(Seq(
|
||||
(stateCurr === STATE_IDLE) -> ( Mux( io.axis.valid, STATE_PREAMBLE, STATE_IDLE )),
|
||||
(stateCurr === STATE_PREAMBLE) -> ( Mux( (byteCnt === (PRE_NUM-1).U) & (bitCnt === 9.U), Mux( io.axis.valid, STATE_PAYLOAD, STATE_IDLE), STATE_PREAMBLE )),
|
||||
(stateCurr === STATE_PAYLOAD) -> ( Mux( (io.axis.fire & io.axis.bits.tlast) | (~io.axis.valid & io.axis.ready), STATE_IDLE, STATE_PAYLOAD ) ),
|
||||
))
|
||||
|
||||
stateNext :=
|
||||
Mux( io.flush, STATE_IDLE,
|
||||
Mux1H(Seq(
|
||||
(stateCurr === STATE_IDLE) -> ( Mux( io.axis.valid, STATE_PREAMBLE, STATE_IDLE )),
|
||||
(stateCurr === STATE_PREAMBLE) -> ( Mux( (byteCnt === (PRE_NUM-1).U) & (bitCnt === 9.U), Mux( io.axis.valid, STATE_PAYLOAD, STATE_IDLE), STATE_PREAMBLE )),
|
||||
(stateCurr === STATE_PAYLOAD) -> ( Mux( (io.axis.fire & io.axis.bits.tlast) | (~io.axis.valid & io.axis.ready), STATE_IDLE, STATE_PAYLOAD ) ),
|
||||
))
|
||||
)
|
||||
io.serDat := shiftData.extract(9)
|
||||
io.axis.ready :=
|
||||
bitCnt === 9.U & (
|
||||
@@ -58,8 +62,9 @@ class CDROut extends Module{
|
||||
}
|
||||
|
||||
|
||||
|
||||
when( stateCurr === STATE_IDLE & stateNext === STATE_PREAMBLE){ //PRE
|
||||
when( io.flush ){
|
||||
shiftData := 0.U
|
||||
} .elsewhen( stateCurr === STATE_IDLE & stateNext === STATE_PREAMBLE){ //PRE
|
||||
shiftData := ETH_PRE
|
||||
} .otherwise{
|
||||
when( bitCnt =/= 9.U ){
|
||||
|
||||
@@ -1,456 +1,456 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.interrupts._
|
||||
|
||||
|
||||
class TL2CDR(implicit p: Parameters) extends LazyModule{
|
||||
val device = new SimpleDevice("TL_CDR", Nil)
|
||||
val node = TLManagerNode(Seq(TLSlavePortParameters.v1(
|
||||
managers = Seq(
|
||||
TLSlaveParameters.v2(
|
||||
address = Seq(AddressSet(0x10000000L, 0xffffL)), //64K
|
||||
name = Some("TL_CDR"),
|
||||
regionType = RegionType.VOLATILE,
|
||||
resources = device.reg,
|
||||
executable = false,
|
||||
fifoId = Some(0),
|
||||
supports = TLMasterToSlaveTransferSizes(
|
||||
get = TransferSizes(1, 32/8),
|
||||
putFull = TransferSizes(1, 32/8),
|
||||
putPartial = TransferSizes(1, 32/8),
|
||||
),
|
||||
)
|
||||
),
|
||||
beatBytes = 32/8)))
|
||||
|
||||
val int_node = IntSourceNode(IntSourcePortSimple(num = 12, resources = device.int))
|
||||
|
||||
lazy val module: TL2CDRImpl = new TL2CDRImpl(this)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
abstract class TL2CDRImplBase(outer: TL2CDR)(implicit p: Parameters) extends LazyModuleImp(outer) {
|
||||
class TLCDRIO extends Bundle{
|
||||
val overCLK = Input(Bool())
|
||||
val dDatIn = Input(Bool())
|
||||
val dDatOut = Output(Bool())
|
||||
val uDatIn = Input(Bool())
|
||||
val uDatOut = Output(Bool())
|
||||
|
||||
val isOnline = Output(Bool())
|
||||
val isLast = Input(Bool())
|
||||
}
|
||||
|
||||
val io: TLCDRIO = IO(new TLCDRIO)
|
||||
|
||||
val ( int, _ ) = outer.int_node.out(0)
|
||||
val ( bus, edge ) = outer.node.in.head
|
||||
|
||||
val CDRIn = for( i <- 0 until 2 ) yield { Module(new CDRIn) }
|
||||
when(true.B){
|
||||
print("Warning!!! New Code has not been reviewed!\n")
|
||||
}
|
||||
|
||||
CDRIn(0).io.serDat := io.dDatIn
|
||||
CDRIn(1).io.serDat := io.uDatIn
|
||||
|
||||
CDRIn(0).overCLK := io.overCLK
|
||||
CDRIn(1).overCLK := io.overCLK
|
||||
|
||||
val CDROut = for( i <- 0 until 2 ) yield { Module(new CDROut) }
|
||||
|
||||
io.dDatOut := CDROut(0).io.serDat
|
||||
io.uDatOut := CDROut(1).io.serDat
|
||||
|
||||
val txFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
|
||||
val rxFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
|
||||
|
||||
val isTLWriteSoftReset = for( i <- 0 until 4 ) yield { Wire(Bool()) }
|
||||
val isTLReadStatus = Wire( Bool() )
|
||||
|
||||
val txLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
|
||||
val rxLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait TL2CDRImplTx{ this: TL2CDRImplBase =>
|
||||
|
||||
|
||||
val isTLWriteTxLen = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
val isTLWriteTxFifo = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
|
||||
|
||||
val isTxFifoRelease = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
val txLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
|
||||
val isTxBusy = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isTxFull = for( i <- 0 until 2 ) yield { ~txFifo(i).io.enq.ready }
|
||||
val intTxFifoFull = for( i <- 0 until 2 ) yield { ~RegNext(isTxFull(i), false.B) & isTxFull(i) }
|
||||
val intTxFinish = for( i <- 0 until 2 ) yield { CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast }
|
||||
val intTxEnd = for( i <- 0 until 2 ) yield { ShiftRegister( intTxFinish(i), 6, false.B, true.B) }
|
||||
|
||||
val intTxFifoDeq = for( i <- 0 until 2 ) yield { txFifo(i).io.deq.fire }
|
||||
// println("Warning, TxEnd no confident\n")
|
||||
|
||||
|
||||
val txCnt = for( i <- 0 until 2 ) yield { Reg(UInt(2.W)) }
|
||||
val txData = for( i <- 0 until 2 ) yield { Reg(UInt(32.W)) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
when( txFifo(i).io.deq.fire ){ //txCnt(i) === 3.U
|
||||
txData(i) := txFifo(i).io.deq.bits
|
||||
when( isTxBusy(i) ){
|
||||
assert(CDROut(i).io.axis.fire)
|
||||
}
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txData(i) := txData(i) << 8
|
||||
}
|
||||
|
||||
txFifo(i).io.deq.ready :=
|
||||
isTxFifoRelease(i) & Mux( isTxBusy(i), CDROut(i).io.axis.fire & txCnt(i) === 3.U, true.B )
|
||||
|
||||
txFifo(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
CDROut(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
|
||||
CDROut(i).io.axis.bits.tdata := txData(i).head(8)
|
||||
CDROut(i).io.axis.bits.tlast := ~txFifo(i).io.deq.valid & txCnt(i) === 3.U
|
||||
CDROut(i).io.axis.bits.tuser := false.B
|
||||
CDROut(i).io.axis.valid := isTxBusy(i)
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(i) ){
|
||||
isTxBusy(i) := false.B
|
||||
}.elsewhen( txFifo(i).io.deq.fire & ~isTxBusy(i) ){
|
||||
isTxBusy(i) := true.B
|
||||
} .elsewhen( CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast ){
|
||||
isTxBusy(i) := false.B
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
txCnt(i) := 0.U
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txCnt(i) := txCnt(i) + 1.U
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteTxLen(i) ){
|
||||
txLen(i) := bus.a.bits.data
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txLen(i) := txLen(i) - 1.U
|
||||
}
|
||||
|
||||
txFifo(i).io.enq.bits := bus.a.bits.data
|
||||
txFifo(i).io.enq.valid := isTLWriteTxFifo(i) & txLen(i) =/= 0.U
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
txLeft(i) := 0.U
|
||||
} .elsewhen( txFifo(i).io.enq.fire & txFifo(i).io.deq.fire ){
|
||||
txLeft(i) := txLeft(i)
|
||||
} .elsewhen( txFifo(i).io.enq.fire ){
|
||||
txLeft(i) := txLeft(i) + 1.U
|
||||
} .elsewhen( txFifo(i).io.deq.fire ){
|
||||
txLeft(i) := txLeft(i) - 1.U
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait TL2CDRImplRx{ this: TL2CDRImplBase =>
|
||||
|
||||
val isTLReadRxLen = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLReadRxFifo = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val rxLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
|
||||
val isRxValid = for( i <- 0 until 2 ) yield { rxFifo(i).io.deq.valid }
|
||||
val isRxError = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isAxisEnd = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isRxEnd = for( i <- 0 until 2 ) yield { isAxisEnd(i) & ~rxFifo(i).io.deq.valid }
|
||||
val intRxError = for( i <- 0 until 2 ) yield { ~RegNext(isRxError(i), false.B) & isRxError(i) }
|
||||
val intRxStart = for( i <- 0 until 2 ) yield { rxLen(i) === 0.U & CDRIn(i).io.axis.fire }
|
||||
val intRxEnd = for( i <- 0 until 2 ) yield { ~RegNext(isRxEnd(i), false.B) & isRxEnd(i) }
|
||||
val intRxFifoEnq = for( i <- 0 until 2 ) yield { rxFifo(i).io.enq.fire }
|
||||
val rxCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(2.W)) }
|
||||
val rxData = for( i <- 0 until 2 ) yield { Reg(UInt(24.W)) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
isAxisEnd(i) := false.B
|
||||
} .elsewhen( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast ){
|
||||
isAxisEnd(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxCnt(i) := 0.U
|
||||
} .elsewhen( CDRIn(i).io.axis.fire ){
|
||||
rxCnt(i) := rxCnt(i) + 1.U
|
||||
rxData(i) := Cat( rxData(i), CDRIn(i).io.axis.bits.tdata )
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxLen(i) := 0.U
|
||||
} .elsewhen( CDRIn(i).io.axis.fire ){
|
||||
rxLen(i) := rxLen(i) + 1.U
|
||||
}
|
||||
|
||||
rxFifo(i).io.enq.valid := CDRIn(i).io.axis.fire & rxCnt(i) === 3.U
|
||||
rxFifo(i).io.enq.bits := Cat( rxData(i)(23, 0) , CDRIn(i).io.axis.bits.tdata )
|
||||
|
||||
assert( ~(( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast) & rxCnt(i) =/= 3.U), "Assert Failed! Rx must 4-byte Align!" )
|
||||
|
||||
CDRIn(i).io.axis.ready := true.B
|
||||
|
||||
rxFifo(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
CDRIn(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
|
||||
rxFifo(i).io.deq.ready := isTLReadRxFifo(i)
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
isRxError(i) := false.B
|
||||
} .elsewhen( rxFifo(i).io.enq.valid & ~rxFifo(i).io.enq.ready ){
|
||||
isRxError(i) := true.B
|
||||
printf(s"Warning, RxFifo$i Overflow!\n")
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxLeft(i) := 0.U
|
||||
} .elsewhen( rxFifo(i).io.enq.fire & rxFifo(i).io.deq.fire ){
|
||||
rxLeft(i) := rxLeft(i)
|
||||
} .elsewhen( rxFifo(i).io.enq.fire ){
|
||||
rxLeft(i) := rxLeft(i) + 1.U
|
||||
} .elsewhen( rxFifo(i).io.deq.fire ){
|
||||
rxLeft(i) := rxLeft(i) - 1.U
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRImplIsLast{ this:TL2CDRImplBase =>
|
||||
io.isOnline := false.B
|
||||
val isReadIsLast = Wire(Bool())
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRImplUserCRC{ this: TL2CDRImplBase =>
|
||||
val isTLWriteTxFifo: Seq[Bool]
|
||||
val isTLReadRxFifo: Seq[Bool]
|
||||
|
||||
val isTLReadTxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLReadRxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
|
||||
val txCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
val rxCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
txCrc(i).io.enq.valid := isTLWriteTxFifo(i)
|
||||
txCrc(i).io.enq.bits := bus.a.bits.data
|
||||
|
||||
rxCrc(i).io.enq.valid := isTLReadRxFifo(i)
|
||||
rxCrc(i).io.enq.bits := rxFifo(i).io.deq.bits
|
||||
|
||||
txCrc(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
rxCrc(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRImplLimitTimmer{ this: TL2CDRImplBase =>
|
||||
val intRxStart: Seq[Bool]
|
||||
val isTLWriteSoftReset: Seq[Bool]
|
||||
val isTxFifoRelease: Seq[Bool]
|
||||
|
||||
val isTLWriteLimitTimerAim = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLWriteLimitTxPair = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val limitTimerCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
|
||||
val limitTimerAim = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
|
||||
val isLimitTimerTrigger = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val txPairSel = for( i <- 0 until 2 ) yield { RegInit((i.U)(2.W)) }
|
||||
|
||||
for( i <- 0 until 2 ){
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
limitTimerCnt(i) := 0.U
|
||||
} .elsewhen( limitTimerCnt(i) =/= limitTimerAim(i) ){
|
||||
when( isLimitTimerTrigger(i) ){
|
||||
limitTimerCnt(i) := limitTimerCnt(i) + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
when( isTLWriteLimitTimerAim(i) ){
|
||||
limitTimerAim(i) := bus.a.bits.data
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
isLimitTimerTrigger(i) := false.B
|
||||
} .elsewhen( intRxStart(i) ){
|
||||
isLimitTimerTrigger(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
txPairSel(i) := i.U
|
||||
} .elsewhen( isTLWriteLimitTxPair(i) ){
|
||||
txPairSel(i) := bus.a.bits.data
|
||||
}
|
||||
|
||||
|
||||
isTxFifoRelease(i) := ( 0 until 2).map{ lmt =>
|
||||
((txPairSel(lmt) =/= i.U) | (limitTimerCnt(lmt) === limitTimerAim(lmt)))
|
||||
}.reduce(_&_)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TL2CDRImpl(outer: TL2CDR)(implicit p: Parameters) extends TL2CDRImplBase(outer)
|
||||
with TL2CDRImplTx with TL2CDRImplRx
|
||||
with TL2CDRImplIsLast
|
||||
with TL2CDRImplUserCRC
|
||||
with TL2CDRImplLimitTimmer
|
||||
{
|
||||
|
||||
isTLWriteSoftReset(0) := bus.a.fire & bus.a.bits.address(7,0) === "h00".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxLen(0) := bus.a.fire & bus.a.bits.address(7,0) === "h04".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxFifo(0) := bus.a.fire & bus.a.bits.address(7,0) === "h08".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadTxCrc(0) := bus.a.fire & bus.a.bits.address(7,0) === "h0c".U & bus.a.bits.opcode === 4.U
|
||||
|
||||
isTLWriteSoftReset(1) := bus.a.fire & bus.a.bits.address(7,0) === "h10".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxLen(1) := bus.a.fire & bus.a.bits.address(7,0) === "h14".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxFifo(1) := bus.a.fire & bus.a.bits.address(7,0) === "h18".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadTxCrc(1) := bus.a.fire & bus.a.bits.address(7,0) === "h1c".U & bus.a.bits.opcode === 4.U
|
||||
|
||||
isTLWriteSoftReset(2) := bus.a.fire & bus.a.bits.address(7,0) === "h20".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadRxLen(0) := bus.a.fire & bus.a.bits.address(7,0) === "h24".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxFifo(0) := bus.a.fire & bus.a.bits.address(7,0) === "h28".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxCrc(0) := bus.a.fire & bus.a.bits.address(7,0) === "h2c".U & bus.a.bits.opcode === 4.U
|
||||
isTLWriteLimitTimerAim(0) := bus.a.fire & bus.a.bits.address(7,0) === "h30".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteLimitTxPair(0) := bus.a.fire & bus.a.bits.address(7,0) === "h34".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
|
||||
isTLWriteSoftReset(3) := bus.a.fire & bus.a.bits.address(7,0) === "h40".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadRxLen(1) := bus.a.fire & bus.a.bits.address(7,0) === "h44".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxFifo(1) := bus.a.fire & bus.a.bits.address(7,0) === "h48".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxCrc(1) := bus.a.fire & bus.a.bits.address(7,0) === "h4c".U & bus.a.bits.opcode === 4.U
|
||||
isTLWriteLimitTimerAim(1) := bus.a.fire & bus.a.bits.address(7,0) === "h50".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteLimitTxPair(1) := bus.a.fire & bus.a.bits.address(7,0) === "h54".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
|
||||
isTLReadStatus := bus.a.fire & bus.a.bits.address(7,0) === "h58".U & ( bus.a.bits.opcode === 4.U )
|
||||
isReadIsLast := bus.a.fire & bus.a.bits.address(7,0) === "h5c".U & ( bus.a.bits.opcode === 4.U )
|
||||
|
||||
int(0) := intTxEnd(0)
|
||||
int(1) := intTxEnd(1)
|
||||
|
||||
int(2) := intRxError(0)
|
||||
int(3) := intRxError(1)
|
||||
|
||||
int(4) := intRxStart(0)
|
||||
int(5) := intRxStart(1)
|
||||
|
||||
int(6) := intRxEnd(0)
|
||||
int(7) := intRxEnd(1)
|
||||
|
||||
int(8) := intTxFifoDeq(0)
|
||||
int(9) := intTxFifoDeq(1)
|
||||
|
||||
int(10) := intRxFifoEnq(0)
|
||||
int(11) := intRxFifoEnq(1)
|
||||
|
||||
|
||||
|
||||
|
||||
val tlaInfo = Reg(new TLBundleA(edge.bundle))
|
||||
val rdata = Reg(UInt(32.W))
|
||||
val tlAReady = RegInit(true.B)
|
||||
val tlDValid = RegInit(false.B)
|
||||
|
||||
val isRead = tlaInfo.opcode === 4.U
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bus.a.ready :=
|
||||
tlAReady &
|
||||
MuxCase( true.B, Array(
|
||||
( bus.a.bits.address(7,0) === "h08".U ) -> txFifo(0).io.enq.ready,
|
||||
( bus.a.bits.address(7,0) === "h18".U ) -> txFifo(1).io.enq.ready,
|
||||
( bus.a.bits.address(7,0) === "h28".U ) -> rxFifo(0).io.deq.valid,
|
||||
( bus.a.bits.address(7,0) === "h48".U ) -> rxFifo(1).io.deq.valid,
|
||||
))
|
||||
|
||||
|
||||
bus.d.valid := tlDValid
|
||||
|
||||
|
||||
|
||||
|
||||
when( bus.a.fire ) {
|
||||
tlaInfo := bus.a.bits
|
||||
}
|
||||
|
||||
when( bus.a.fire ){
|
||||
tlAReady := false.B
|
||||
tlDValid := true.B
|
||||
} .elsewhen( bus.d.fire ) {
|
||||
tlAReady := true.B
|
||||
tlDValid := false.B
|
||||
}
|
||||
|
||||
when(isRead) {
|
||||
bus.d.bits := edge.AccessAck(tlaInfo, rdata)
|
||||
} .otherwise {
|
||||
bus.d.bits := edge.AccessAck(tlaInfo)
|
||||
}
|
||||
|
||||
|
||||
when( isTLReadStatus ){
|
||||
rdata := Cat( txLeft(1), txLeft(0), rxLeft(1), rxLeft(0), isRxValid(1), isRxValid(0), isRxError(1), isRxError(0), isTxBusy(1), isTxBusy(0), isTxFull(1), isTxFull(0) )
|
||||
} .elsewhen(isTLReadRxLen(0) ){
|
||||
rdata := rxLen(0)
|
||||
} .elsewhen(isTLReadRxLen(1) ){
|
||||
rdata := rxLen(1)
|
||||
} .elsewhen(isTLReadRxFifo(0) ){
|
||||
rdata := rxFifo(0).io.deq.bits
|
||||
} .elsewhen(isTLReadRxFifo(1) ){
|
||||
rdata := rxFifo(1).io.deq.bits
|
||||
} .elsewhen(isReadIsLast){
|
||||
rdata := io.isLast
|
||||
} .elsewhen(isTLReadTxCrc(0)){
|
||||
rdata := txCrc(0).io.crc
|
||||
} .elsewhen(isTLReadTxCrc(1)){
|
||||
rdata := txCrc(1).io.crc
|
||||
} .elsewhen(isTLReadRxCrc(0)){
|
||||
rdata := rxCrc(0).io.crc
|
||||
} .elsewhen(isTLReadRxCrc(1)){
|
||||
rdata := rxCrc(1).io.crc
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.interrupts._
|
||||
|
||||
|
||||
class TL2CDR(implicit p: Parameters) extends LazyModule{
|
||||
val device = new SimpleDevice("TL_CDR", Nil)
|
||||
val node = TLManagerNode(Seq(TLSlavePortParameters.v1(
|
||||
managers = Seq(
|
||||
TLSlaveParameters.v2(
|
||||
address = Seq(AddressSet(0x10000000L, 0xffffL)), //64K
|
||||
name = Some("TL_CDR"),
|
||||
regionType = RegionType.VOLATILE,
|
||||
resources = device.reg,
|
||||
executable = false,
|
||||
fifoId = Some(0),
|
||||
supports = TLMasterToSlaveTransferSizes(
|
||||
get = TransferSizes(1, 32/8),
|
||||
putFull = TransferSizes(1, 32/8),
|
||||
putPartial = TransferSizes(1, 32/8),
|
||||
),
|
||||
)
|
||||
),
|
||||
beatBytes = 32/8)))
|
||||
|
||||
val int_node = IntSourceNode(IntSourcePortSimple(num = 12, resources = device.int))
|
||||
|
||||
lazy val module: TL2CDRImpl = new TL2CDRImpl(this)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
abstract class TL2CDRImplBase(outer: TL2CDR)(implicit p: Parameters) extends LazyModuleImp(outer) {
|
||||
class TLCDRIO extends Bundle{
|
||||
val overCLK = Input(Bool())
|
||||
val dDatIn = Input(Bool())
|
||||
val dDatOut = Output(Bool())
|
||||
val uDatIn = Input(Bool())
|
||||
val uDatOut = Output(Bool())
|
||||
|
||||
val isOnline = Output(Bool())
|
||||
val isLast = Input(Bool())
|
||||
}
|
||||
|
||||
val io: TLCDRIO = IO(new TLCDRIO)
|
||||
|
||||
val ( int, _ ) = outer.int_node.out(0)
|
||||
val ( bus, edge ) = outer.node.in.head
|
||||
|
||||
val CDRIn = for( i <- 0 until 2 ) yield { Module(new CDRIn) }
|
||||
when(true.B){
|
||||
print("Warning!!! New Code has not been reviewed!\n")
|
||||
}
|
||||
|
||||
CDRIn(0).io.serDat := io.dDatIn
|
||||
CDRIn(1).io.serDat := io.uDatIn
|
||||
|
||||
CDRIn(0).overCLK := io.overCLK
|
||||
CDRIn(1).overCLK := io.overCLK
|
||||
|
||||
val CDROut = for( i <- 0 until 2 ) yield { Module(new CDROut) }
|
||||
|
||||
io.dDatOut := CDROut(0).io.serDat
|
||||
io.uDatOut := CDROut(1).io.serDat
|
||||
|
||||
val txFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
|
||||
val rxFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
|
||||
|
||||
val isTLWriteSoftReset = for( i <- 0 until 4 ) yield { Wire(Bool()) }
|
||||
val isTLReadStatus = Wire( Bool() )
|
||||
|
||||
val txLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
|
||||
val rxLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait TL2CDRImplTx{ this: TL2CDRImplBase =>
|
||||
|
||||
|
||||
val isTLWriteTxLen = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
val isTLWriteTxFifo = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
|
||||
|
||||
val isTxFifoRelease = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
val txLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
|
||||
val isTxBusy = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isTxFull = for( i <- 0 until 2 ) yield { ~txFifo(i).io.enq.ready }
|
||||
val intTxFifoFull = for( i <- 0 until 2 ) yield { ~RegNext(isTxFull(i), false.B) & isTxFull(i) }
|
||||
val intTxFinish = for( i <- 0 until 2 ) yield { CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast }
|
||||
val intTxEnd = for( i <- 0 until 2 ) yield { ShiftRegister( intTxFinish(i), 6, false.B, true.B) }
|
||||
|
||||
val intTxFifoDeq = for( i <- 0 until 2 ) yield { txFifo(i).io.deq.fire }
|
||||
// println("Warning, TxEnd no confident\n")
|
||||
|
||||
|
||||
val txCnt = for( i <- 0 until 2 ) yield { Reg(UInt(2.W)) }
|
||||
val txData = for( i <- 0 until 2 ) yield { Reg(UInt(32.W)) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
when( txFifo(i).io.deq.fire ){ //txCnt(i) === 3.U
|
||||
txData(i) := txFifo(i).io.deq.bits
|
||||
when( isTxBusy(i) ){
|
||||
assert(CDROut(i).io.axis.fire)
|
||||
}
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txData(i) := txData(i) << 8
|
||||
}
|
||||
|
||||
txFifo(i).io.deq.ready :=
|
||||
isTxFifoRelease(i) & Mux( isTxBusy(i), CDROut(i).io.axis.fire & txCnt(i) === 3.U, true.B )
|
||||
|
||||
txFifo(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
CDROut(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
|
||||
CDROut(i).io.axis.bits.tdata := txData(i).head(8)
|
||||
CDROut(i).io.axis.bits.tlast := ~txFifo(i).io.deq.valid & txCnt(i) === 3.U
|
||||
CDROut(i).io.axis.bits.tuser := false.B
|
||||
CDROut(i).io.axis.valid := isTxBusy(i)
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(i) ){
|
||||
isTxBusy(i) := false.B
|
||||
}.elsewhen( txFifo(i).io.deq.fire & ~isTxBusy(i) ){
|
||||
isTxBusy(i) := true.B
|
||||
} .elsewhen( CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast ){
|
||||
isTxBusy(i) := false.B
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
txCnt(i) := 0.U
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txCnt(i) := txCnt(i) + 1.U
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteTxLen(i) ){
|
||||
txLen(i) := bus.a.bits.data
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txLen(i) := txLen(i) - 1.U
|
||||
}
|
||||
|
||||
txFifo(i).io.enq.bits := bus.a.bits.data
|
||||
txFifo(i).io.enq.valid := isTLWriteTxFifo(i) & txLen(i) =/= 0.U
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
txLeft(i) := 0.U
|
||||
} .elsewhen( txFifo(i).io.enq.fire & txFifo(i).io.deq.fire ){
|
||||
txLeft(i) := txLeft(i)
|
||||
} .elsewhen( txFifo(i).io.enq.fire ){
|
||||
txLeft(i) := txLeft(i) + 1.U
|
||||
} .elsewhen( txFifo(i).io.deq.fire ){
|
||||
txLeft(i) := txLeft(i) - 1.U
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait TL2CDRImplRx{ this: TL2CDRImplBase =>
|
||||
|
||||
val isTLReadRxLen = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLReadRxFifo = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val rxLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
|
||||
val isRxValid = for( i <- 0 until 2 ) yield { rxFifo(i).io.deq.valid }
|
||||
val isRxError = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isAxisEnd = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isRxEnd = for( i <- 0 until 2 ) yield { isAxisEnd(i) & ~rxFifo(i).io.deq.valid }
|
||||
val intRxError = for( i <- 0 until 2 ) yield { ~RegNext(isRxError(i), false.B) & isRxError(i) }
|
||||
val intRxStart = for( i <- 0 until 2 ) yield { rxLen(i) === 0.U & CDRIn(i).io.axis.fire }
|
||||
val intRxEnd = for( i <- 0 until 2 ) yield { ~RegNext(isRxEnd(i), false.B) & isRxEnd(i) }
|
||||
val intRxFifoEnq = for( i <- 0 until 2 ) yield { rxFifo(i).io.enq.fire }
|
||||
val rxCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(2.W)) }
|
||||
val rxData = for( i <- 0 until 2 ) yield { Reg(UInt(24.W)) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
isAxisEnd(i) := false.B
|
||||
} .elsewhen( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast ){
|
||||
isAxisEnd(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxCnt(i) := 0.U
|
||||
} .elsewhen( CDRIn(i).io.axis.fire ){
|
||||
rxCnt(i) := rxCnt(i) + 1.U
|
||||
rxData(i) := Cat( rxData(i), CDRIn(i).io.axis.bits.tdata )
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxLen(i) := 0.U
|
||||
} .elsewhen( CDRIn(i).io.axis.fire ){
|
||||
rxLen(i) := rxLen(i) + 1.U
|
||||
}
|
||||
|
||||
rxFifo(i).io.enq.valid := CDRIn(i).io.axis.fire & rxCnt(i) === 3.U
|
||||
rxFifo(i).io.enq.bits := Cat( rxData(i)(23, 0) , CDRIn(i).io.axis.bits.tdata )
|
||||
|
||||
assert( ~(( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast) & rxCnt(i) =/= 3.U), "Assert Failed! Rx must 4-byte Align!" )
|
||||
|
||||
CDRIn(i).io.axis.ready := true.B
|
||||
|
||||
rxFifo(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
CDRIn(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
|
||||
rxFifo(i).io.deq.ready := isTLReadRxFifo(i)
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
isRxError(i) := false.B
|
||||
} .elsewhen( rxFifo(i).io.enq.valid & ~rxFifo(i).io.enq.ready ){
|
||||
isRxError(i) := true.B
|
||||
printf(s"Warning, RxFifo$i Overflow!\n")
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxLeft(i) := 0.U
|
||||
} .elsewhen( rxFifo(i).io.enq.fire & rxFifo(i).io.deq.fire ){
|
||||
rxLeft(i) := rxLeft(i)
|
||||
} .elsewhen( rxFifo(i).io.enq.fire ){
|
||||
rxLeft(i) := rxLeft(i) + 1.U
|
||||
} .elsewhen( rxFifo(i).io.deq.fire ){
|
||||
rxLeft(i) := rxLeft(i) - 1.U
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRImplIsLast{ this:TL2CDRImplBase =>
|
||||
io.isOnline := false.B
|
||||
val isReadIsLast = Wire(Bool())
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRImplUserCRC{ this: TL2CDRImplBase =>
|
||||
val isTLWriteTxFifo: Seq[Bool]
|
||||
val isTLReadRxFifo: Seq[Bool]
|
||||
|
||||
val isTLReadTxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLReadRxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
|
||||
val txCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
val rxCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
txCrc(i).io.enq.valid := isTLWriteTxFifo(i)
|
||||
txCrc(i).io.enq.bits := bus.a.bits.data
|
||||
|
||||
rxCrc(i).io.enq.valid := isTLReadRxFifo(i)
|
||||
rxCrc(i).io.enq.bits := rxFifo(i).io.deq.bits
|
||||
|
||||
txCrc(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
rxCrc(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRImplLimitTimmer{ this: TL2CDRImplBase =>
|
||||
val intRxStart: Seq[Bool]
|
||||
val isTLWriteSoftReset: Seq[Bool]
|
||||
val isTxFifoRelease: Seq[Bool]
|
||||
|
||||
val isTLWriteLimitTimerAim = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLWriteLimitTxPair = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val limitTimerCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
|
||||
val limitTimerAim = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
|
||||
val isLimitTimerTrigger = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val txPairSel = for( i <- 0 until 2 ) yield { RegInit((i.U)(2.W)) }
|
||||
|
||||
for( i <- 0 until 2 ){
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
limitTimerCnt(i) := 0.U
|
||||
} .elsewhen( limitTimerCnt(i) =/= limitTimerAim(i) ){
|
||||
when( isLimitTimerTrigger(i) ){
|
||||
limitTimerCnt(i) := limitTimerCnt(i) + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
when( isTLWriteLimitTimerAim(i) ){
|
||||
limitTimerAim(i) := bus.a.bits.data
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
isLimitTimerTrigger(i) := false.B
|
||||
} .elsewhen( intRxStart(i) ){
|
||||
isLimitTimerTrigger(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
txPairSel(i) := i.U
|
||||
} .elsewhen( isTLWriteLimitTxPair(i) ){
|
||||
txPairSel(i) := bus.a.bits.data
|
||||
}
|
||||
|
||||
|
||||
isTxFifoRelease(i) := ( 0 until 2).map{ lmt =>
|
||||
((txPairSel(lmt) =/= i.U) | (limitTimerCnt(lmt) === limitTimerAim(lmt)))
|
||||
}.reduce(_&_)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TL2CDRImpl(outer: TL2CDR)(implicit p: Parameters) extends TL2CDRImplBase(outer)
|
||||
with TL2CDRImplTx with TL2CDRImplRx
|
||||
with TL2CDRImplIsLast
|
||||
with TL2CDRImplUserCRC
|
||||
with TL2CDRImplLimitTimmer
|
||||
{
|
||||
|
||||
isTLWriteSoftReset(0) := bus.a.fire & bus.a.bits.address(7,0) === "h00".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxLen(0) := bus.a.fire & bus.a.bits.address(7,0) === "h04".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxFifo(0) := bus.a.fire & bus.a.bits.address(7,0) === "h08".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadTxCrc(0) := bus.a.fire & bus.a.bits.address(7,0) === "h0c".U & bus.a.bits.opcode === 4.U
|
||||
|
||||
isTLWriteSoftReset(1) := bus.a.fire & bus.a.bits.address(7,0) === "h10".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxLen(1) := bus.a.fire & bus.a.bits.address(7,0) === "h14".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxFifo(1) := bus.a.fire & bus.a.bits.address(7,0) === "h18".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadTxCrc(1) := bus.a.fire & bus.a.bits.address(7,0) === "h1c".U & bus.a.bits.opcode === 4.U
|
||||
|
||||
isTLWriteSoftReset(2) := bus.a.fire & bus.a.bits.address(7,0) === "h20".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadRxLen(0) := bus.a.fire & bus.a.bits.address(7,0) === "h24".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxFifo(0) := bus.a.fire & bus.a.bits.address(7,0) === "h28".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxCrc(0) := bus.a.fire & bus.a.bits.address(7,0) === "h2c".U & bus.a.bits.opcode === 4.U
|
||||
isTLWriteLimitTimerAim(0) := bus.a.fire & bus.a.bits.address(7,0) === "h30".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteLimitTxPair(0) := bus.a.fire & bus.a.bits.address(7,0) === "h34".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
|
||||
isTLWriteSoftReset(3) := bus.a.fire & bus.a.bits.address(7,0) === "h40".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadRxLen(1) := bus.a.fire & bus.a.bits.address(7,0) === "h44".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxFifo(1) := bus.a.fire & bus.a.bits.address(7,0) === "h48".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxCrc(1) := bus.a.fire & bus.a.bits.address(7,0) === "h4c".U & bus.a.bits.opcode === 4.U
|
||||
isTLWriteLimitTimerAim(1) := bus.a.fire & bus.a.bits.address(7,0) === "h50".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteLimitTxPair(1) := bus.a.fire & bus.a.bits.address(7,0) === "h54".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
|
||||
isTLReadStatus := bus.a.fire & bus.a.bits.address(7,0) === "h58".U & ( bus.a.bits.opcode === 4.U )
|
||||
isReadIsLast := bus.a.fire & bus.a.bits.address(7,0) === "h5c".U & ( bus.a.bits.opcode === 4.U )
|
||||
|
||||
int(0) := intTxEnd(0)
|
||||
int(1) := intTxEnd(1)
|
||||
|
||||
int(2) := intRxError(0)
|
||||
int(3) := intRxError(1)
|
||||
|
||||
int(4) := intRxStart(0)
|
||||
int(5) := intRxStart(1)
|
||||
|
||||
int(6) := intRxEnd(0)
|
||||
int(7) := intRxEnd(1)
|
||||
|
||||
int(8) := intTxFifoDeq(0)
|
||||
int(9) := intTxFifoDeq(1)
|
||||
|
||||
int(10) := intRxFifoEnq(0)
|
||||
int(11) := intRxFifoEnq(1)
|
||||
|
||||
|
||||
|
||||
|
||||
val tlaInfo = Reg(new TLBundleA(edge.bundle))
|
||||
val rdata = Reg(UInt(32.W))
|
||||
val tlAReady = RegInit(true.B)
|
||||
val tlDValid = RegInit(false.B)
|
||||
|
||||
val isRead = tlaInfo.opcode === 4.U
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bus.a.ready :=
|
||||
tlAReady &
|
||||
MuxCase( true.B, Array(
|
||||
( bus.a.bits.address(7,0) === "h08".U ) -> txFifo(0).io.enq.ready,
|
||||
( bus.a.bits.address(7,0) === "h18".U ) -> txFifo(1).io.enq.ready,
|
||||
( bus.a.bits.address(7,0) === "h28".U ) -> rxFifo(0).io.deq.valid,
|
||||
( bus.a.bits.address(7,0) === "h48".U ) -> rxFifo(1).io.deq.valid,
|
||||
))
|
||||
|
||||
|
||||
bus.d.valid := tlDValid
|
||||
|
||||
|
||||
|
||||
|
||||
when( bus.a.fire ) {
|
||||
tlaInfo := bus.a.bits
|
||||
}
|
||||
|
||||
when( bus.a.fire ){
|
||||
tlAReady := false.B
|
||||
tlDValid := true.B
|
||||
} .elsewhen( bus.d.fire ) {
|
||||
tlAReady := true.B
|
||||
tlDValid := false.B
|
||||
}
|
||||
|
||||
when(isRead) {
|
||||
bus.d.bits := edge.AccessAck(tlaInfo, rdata)
|
||||
} .otherwise {
|
||||
bus.d.bits := edge.AccessAck(tlaInfo)
|
||||
}
|
||||
|
||||
|
||||
when( isTLReadStatus ){
|
||||
rdata := Cat( txLeft(1), txLeft(0), rxLeft(1), rxLeft(0), isRxValid(1), isRxValid(0), isRxError(1), isRxError(0), isTxBusy(1), isTxBusy(0), isTxFull(1), isTxFull(0) )
|
||||
} .elsewhen(isTLReadRxLen(0) ){
|
||||
rdata := rxLen(0)
|
||||
} .elsewhen(isTLReadRxLen(1) ){
|
||||
rdata := rxLen(1)
|
||||
} .elsewhen(isTLReadRxFifo(0) ){
|
||||
rdata := rxFifo(0).io.deq.bits
|
||||
} .elsewhen(isTLReadRxFifo(1) ){
|
||||
rdata := rxFifo(1).io.deq.bits
|
||||
} .elsewhen(isReadIsLast){
|
||||
rdata := io.isLast
|
||||
} .elsewhen(isTLReadTxCrc(0)){
|
||||
rdata := txCrc(0).io.crc
|
||||
} .elsewhen(isTLReadTxCrc(1)){
|
||||
rdata := txCrc(1).io.crc
|
||||
} .elsewhen(isTLReadRxCrc(0)){
|
||||
rdata := rxCrc(0).io.crc
|
||||
} .elsewhen(isTLReadRxCrc(1)){
|
||||
rdata := rxCrc(1).io.crc
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -86,12 +86,13 @@ import chisel3.util._
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class crc32_8() extends Module{
|
||||
class crc32_8() extends Module with RequireAsyncReset{
|
||||
class crc32IO_Bundle extends Bundle{
|
||||
val isEnable = Input(Bool())
|
||||
val dataIn = Input(UInt(8.W))
|
||||
|
||||
val crc = Output(UInt(32.W))
|
||||
val flush = Input(Bool())
|
||||
}
|
||||
|
||||
val io = IO( new crc32IO_Bundle )
|
||||
@@ -99,7 +100,16 @@ class crc32_8() extends Module{
|
||||
// val LFSR_POLY = "h4c11db7".U
|
||||
|
||||
val lfsr_c = for( i <- 0 until 32 ) yield Wire(Bool())
|
||||
val lfsr_q = for( i <- 0 until 32 ) yield RegEnable( lfsr_c(i), true.B, io.isEnable )
|
||||
val lfsr_q = for( i <- 0 until 32 ) yield RegInit( true.B )
|
||||
|
||||
for( i <- 0 until 32 ){
|
||||
when( io.flush ){
|
||||
lfsr_q(i) := true.B
|
||||
} .elsewhen( io.isEnable ){
|
||||
lfsr_q(i) := lfsr_c(i)
|
||||
}
|
||||
}
|
||||
|
||||
io.crc := Cat( lfsr_q )
|
||||
|
||||
val dataIn = Wire(UInt(8.W))
|
||||
@@ -142,67 +152,3 @@ class crc32_8() extends Module{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class crc32_32() extends Module{
|
||||
val io = IO(new Bundle{
|
||||
val enq = Flipped(Valid(UInt(32.W)))
|
||||
val crc = Output(UInt(32.W))
|
||||
})
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 OutputLogic.com
|
||||
// This source file may be used and distributed without restriction
|
||||
// provided that this copyright statement is not removed from the file
|
||||
// and that any derivative work contains the original copyright notice
|
||||
// and the associated disclaimer.
|
||||
//
|
||||
// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
|
||||
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//-----------------------------------------------------------------------------
|
||||
// CRC module for data(31:0) , crc(31:0)=1+x^1+x^2+x^4+x^5+x^7+x^8+x^10+x^11+x^12+x^16+x^22+x^23+x^26+x^32;
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
val lfsr_c = Wire(Vec(32, UInt(1.W)))
|
||||
val lfsr_q = RegEnable( Cat(lfsr_c.reverse), "hffffffff".U(32.W), io.enq.valid)
|
||||
|
||||
io.crc := lfsr_q
|
||||
|
||||
lfsr_c( 0) := lfsr_q(0) ^ lfsr_q(6) ^ lfsr_q( 9) ^ lfsr_q(10) ^ lfsr_q(12) ^ lfsr_q(16) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(6) ^ io.enq.bits(9) ^ io.enq.bits(10) ^ io.enq.bits(12) ^ io.enq.bits(16) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
||||
lfsr_c( 1) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q( 9) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(13) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(24) ^ lfsr_q(27) ^ lfsr_q(28) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(9) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(13) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(24) ^ io.enq.bits(27) ^ io.enq.bits(28);
|
||||
lfsr_c( 2) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 2) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
||||
lfsr_c( 3) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q( 9) ^ lfsr_q(10) ^ lfsr_q(14) ^ lfsr_q(15) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(31) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(10) ^ io.enq.bits(14) ^ io.enq.bits(15) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(25) ^ io.enq.bits(27) ^ io.enq.bits(31);
|
||||
lfsr_c( 4) := lfsr_q(0) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 4) ^ lfsr_q( 6) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(15) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(6) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(15) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(29) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
||||
lfsr_c( 5) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 3) ^ lfsr_q( 4) ^ lfsr_q( 5) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q(10) ^ lfsr_q(13) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(24) ^ lfsr_q(28) ^ lfsr_q(29) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(10) ^ io.enq.bits(13) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(24) ^ io.enq.bits(28) ^ io.enq.bits(29);
|
||||
lfsr_c( 6) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 4) ^ lfsr_q( 5) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(14) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(25) ^ lfsr_q(29) ^ lfsr_q(30) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(14) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(25) ^ io.enq.bits(29) ^ io.enq.bits(30);
|
||||
lfsr_c( 7) := lfsr_q(0) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 5) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q(10) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(28) ^ lfsr_q(29) ^ io.enq.bits(0) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(5) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(10) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(28) ^ io.enq.bits(29);
|
||||
lfsr_c( 8) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 3) ^ lfsr_q( 4) ^ lfsr_q( 8) ^ lfsr_q(10) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(17) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(8) ^ io.enq.bits(10) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(17) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
||||
lfsr_c( 9) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 4) ^ lfsr_q( 5) ^ lfsr_q( 9) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(13) ^ lfsr_q(18) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(29) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(9) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(13) ^ io.enq.bits(18) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(29);
|
||||
lfsr_c(10) := lfsr_q(0) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 5) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(19) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(5) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(19) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
||||
lfsr_c(11) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 3) ^ lfsr_q( 4) ^ lfsr_q( 9) ^ lfsr_q(12) ^ lfsr_q(14) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(20) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(9) ^ io.enq.bits(12) ^ io.enq.bits(14) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(20) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
||||
lfsr_c(12) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 2) ^ lfsr_q( 4) ^ lfsr_q( 5) ^ lfsr_q( 6) ^ lfsr_q( 9) ^ lfsr_q(12) ^ lfsr_q(13) ^ lfsr_q(15) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(21) ^ lfsr_q(24) ^ lfsr_q(27) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(9) ^ io.enq.bits(12) ^ io.enq.bits(13) ^ io.enq.bits(15) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(21) ^ io.enq.bits(24) ^ io.enq.bits(27) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
||||
lfsr_c(13) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 3) ^ lfsr_q( 5) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q(10) ^ lfsr_q(13) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(22) ^ lfsr_q(25) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(10) ^ io.enq.bits(13) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(22) ^ io.enq.bits(25) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
||||
lfsr_c(14) := lfsr_q(2) ^ lfsr_q(3) ^ lfsr_q( 4) ^ lfsr_q( 6) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(14) ^ lfsr_q(15) ^ lfsr_q(17) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(23) ^ lfsr_q(26) ^ lfsr_q(29) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(14) ^ io.enq.bits(15) ^ io.enq.bits(17) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(23) ^ io.enq.bits(26) ^ io.enq.bits(29);
|
||||
lfsr_c(15) := lfsr_q(3) ^ lfsr_q(4) ^ lfsr_q( 5) ^ lfsr_q( 7) ^ lfsr_q( 8) ^ lfsr_q( 9) ^ lfsr_q(12) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(18) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(24) ^ lfsr_q(27) ^ lfsr_q(30) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(12) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(18) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(24) ^ io.enq.bits(27) ^ io.enq.bits(30);
|
||||
lfsr_c(16) := lfsr_q(0) ^ lfsr_q(4) ^ lfsr_q( 5) ^ lfsr_q( 8) ^ lfsr_q(12) ^ lfsr_q(13) ^ lfsr_q(17) ^ lfsr_q(19) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(29) ^ lfsr_q(30) ^ io.enq.bits(0) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(8) ^ io.enq.bits(12) ^ io.enq.bits(13) ^ io.enq.bits(17) ^ io.enq.bits(19) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(29) ^ io.enq.bits(30);
|
||||
lfsr_c(17) := lfsr_q(1) ^ lfsr_q(5) ^ lfsr_q( 6) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(14) ^ lfsr_q(18) ^ lfsr_q(20) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(1) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(14) ^ io.enq.bits(18) ^ io.enq.bits(20) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(25) ^ io.enq.bits(27) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
||||
lfsr_c(18) := lfsr_q(2) ^ lfsr_q(6) ^ lfsr_q( 7) ^ lfsr_q(10) ^ lfsr_q(14) ^ lfsr_q(15) ^ lfsr_q(19) ^ lfsr_q(21) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(2) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(10) ^ io.enq.bits(14) ^ io.enq.bits(15) ^ io.enq.bits(19) ^ io.enq.bits(21) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
||||
lfsr_c(19) := lfsr_q(3) ^ lfsr_q(7) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(20) ^ lfsr_q(22) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(29) ^ io.enq.bits(3) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(20) ^ io.enq.bits(22) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(27) ^ io.enq.bits(29);
|
||||
lfsr_c(20) := lfsr_q(4) ^ lfsr_q(8) ^ lfsr_q( 9) ^ lfsr_q(12) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(21) ^ lfsr_q(23) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(30) ^ io.enq.bits(4) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(12) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(21) ^ io.enq.bits(23) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(30);
|
||||
lfsr_c(21) := lfsr_q(5) ^ lfsr_q(9) ^ lfsr_q(10) ^ lfsr_q(13) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(22) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(5) ^ io.enq.bits(9) ^ io.enq.bits(10) ^ io.enq.bits(13) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(22) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
||||
lfsr_c(22) := lfsr_q(0) ^ lfsr_q(9) ^ lfsr_q(11) ^ lfsr_q(12) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(9) ^ io.enq.bits(11) ^ io.enq.bits(12) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
||||
lfsr_c(23) := lfsr_q(0) ^ lfsr_q(1) ^ lfsr_q( 6) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(15) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(1) ^ io.enq.bits(6) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(15) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
||||
lfsr_c(24) := lfsr_q(1) ^ lfsr_q(2) ^ lfsr_q( 7) ^ lfsr_q(10) ^ lfsr_q(14) ^ lfsr_q(16) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ io.enq.bits(1) ^ io.enq.bits(2) ^ io.enq.bits(7) ^ io.enq.bits(10) ^ io.enq.bits(14) ^ io.enq.bits(16) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(30);
|
||||
lfsr_c(25) := lfsr_q(2) ^ lfsr_q(3) ^ lfsr_q( 8) ^ lfsr_q(11) ^ lfsr_q(15) ^ lfsr_q(17) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(2) ^ io.enq.bits(3) ^ io.enq.bits(8) ^ io.enq.bits(11) ^ io.enq.bits(15) ^ io.enq.bits(17) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
||||
lfsr_c(26) := lfsr_q(0) ^ lfsr_q(3) ^ lfsr_q( 4) ^ lfsr_q( 6) ^ lfsr_q(10) ^ lfsr_q(18) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(31) ^ io.enq.bits(0) ^ io.enq.bits(3) ^ io.enq.bits(4) ^ io.enq.bits(6) ^ io.enq.bits(10) ^ io.enq.bits(18) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(28) ^ io.enq.bits(31);
|
||||
lfsr_c(27) := lfsr_q(1) ^ lfsr_q(4) ^ lfsr_q( 5) ^ lfsr_q( 7) ^ lfsr_q(11) ^ lfsr_q(19) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ io.enq.bits(1) ^ io.enq.bits(4) ^ io.enq.bits(5) ^ io.enq.bits(7) ^ io.enq.bits(11) ^ io.enq.bits(19) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(29);
|
||||
lfsr_c(28) := lfsr_q(2) ^ lfsr_q(5) ^ lfsr_q( 6) ^ lfsr_q( 8) ^ lfsr_q(12) ^ lfsr_q(20) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ io.enq.bits(2) ^ io.enq.bits(5) ^ io.enq.bits(6) ^ io.enq.bits(8) ^ io.enq.bits(12) ^ io.enq.bits(20) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(30);
|
||||
lfsr_c(29) := lfsr_q(3) ^ lfsr_q(6) ^ lfsr_q( 7) ^ lfsr_q( 9) ^ lfsr_q(13) ^ lfsr_q(21) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ io.enq.bits(3) ^ io.enq.bits(6) ^ io.enq.bits(7) ^ io.enq.bits(9) ^ io.enq.bits(13) ^ io.enq.bits(21) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(25) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(31);
|
||||
lfsr_c(30) := lfsr_q(4) ^ lfsr_q(7) ^ lfsr_q( 8) ^ lfsr_q(10) ^ lfsr_q(14) ^ lfsr_q(22) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ io.enq.bits(4) ^ io.enq.bits(7) ^ io.enq.bits(8) ^ io.enq.bits(10) ^ io.enq.bits(14) ^ io.enq.bits(22) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(26) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(30);
|
||||
lfsr_c(31) := lfsr_q(5) ^ lfsr_q(8) ^ lfsr_q( 9) ^ lfsr_q(11) ^ lfsr_q(15) ^ lfsr_q(23) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ io.enq.bits(5) ^ io.enq.bits(8) ^ io.enq.bits(9) ^ io.enq.bits(11) ^ io.enq.bits(15) ^ io.enq.bits(23) ^ io.enq.bits(24) ^ io.enq.bits(25) ^ io.enq.bits(27) ^ io.enq.bits(28) ^ io.enq.bits(29) ^ io.enq.bits(30) ^ io.enq.bits(31);
|
||||
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ class SlaveRegisterBundle extends Bundle{
|
||||
|
||||
|
||||
val slvDeltaTime = UInt(32.W) //从站时间戳差值
|
||||
val deltaFinal = UInt(32.W) //当前时间戳与主站时间差
|
||||
val deltaFinal = UInt(64.W) //当前时间戳与主站时间差
|
||||
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ class InterfaceIO extends Bundle{
|
||||
|
||||
val slvDeltaTime = Input(UInt(32.W)) //从站时间戳差值
|
||||
val mstDeltaTime = Input(UInt(32.W))
|
||||
val deltaFinal = Input(UInt(32.W))
|
||||
val deltaFinal = Input(UInt(64.W))
|
||||
|
||||
val sync = Output(Vec(4, Bool()))
|
||||
|
||||
@@ -213,7 +213,7 @@ class InterfaceIO extends Bundle{
|
||||
}
|
||||
|
||||
|
||||
abstract class InterfaceBase extends Module{
|
||||
abstract class InterfaceBase extends Module with RequireAsyncReset{
|
||||
val io: InterfaceIO = IO(new InterfaceIO)
|
||||
|
||||
val oSpi = Module(new SSpiInterface)
|
||||
@@ -379,23 +379,23 @@ abstract class InterfaceBase extends Module{
|
||||
Seq(
|
||||
//本地时钟
|
||||
(addr === "h100".U ) -> cReg.timeStamp(7,0),
|
||||
(addr === "h101".U ) -> cReg.timeStamp(15,8),
|
||||
(addr === "h102".U ) -> cReg.timeStamp(23,16),
|
||||
(addr === "h103".U ) -> cReg.timeStamp(31,24),
|
||||
(addr === "h104".U ) -> cReg.timeStamp(39,32),
|
||||
(addr === "h105".U ) -> cReg.timeStamp(47,40),
|
||||
(addr === "h106".U ) -> cReg.timeStamp(55,48),
|
||||
(addr === "h107".U ) -> cReg.timeStamp(63,56),
|
||||
(addr === "h101".U ) -> RegEnable(cReg.timeStamp(15,8), isEnR & (addrr === "h100".U)),
|
||||
(addr === "h102".U ) -> RegEnable(cReg.timeStamp(23,16), isEnR & (addrr === "h100".U)),
|
||||
(addr === "h103".U ) -> RegEnable(cReg.timeStamp(31,24), isEnR & (addrr === "h100".U)),
|
||||
(addr === "h104".U ) -> RegEnable(cReg.timeStamp(39,32), isEnR & (addrr === "h100".U)),
|
||||
(addr === "h105".U ) -> RegEnable(cReg.timeStamp(47,40), isEnR & (addrr === "h100".U)),
|
||||
(addr === "h106".U ) -> RegEnable(cReg.timeStamp(55,48), isEnR & (addrr === "h100".U)),
|
||||
(addr === "h107".U ) -> RegEnable(cReg.timeStamp(63,56), isEnR & (addrr === "h100".U)),
|
||||
|
||||
//参考主站时钟
|
||||
(addr === "h108".U & isSlvMode) -> sReg.deltaFinal(7,0),
|
||||
(addr === "h109".U & isSlvMode) -> sReg.deltaFinal(15,8),
|
||||
(addr === "h10a".U & isSlvMode) -> sReg.deltaFinal(23,16),
|
||||
(addr === "h10b".U & isSlvMode) -> sReg.deltaFinal(31,24),
|
||||
// (addr === "h10c".U & isSlvMode) -> sReg.deltaFinal(39,32),
|
||||
// (addr === "h10d".U & isSlvMode) -> sReg.deltaFinal(47,40),
|
||||
// (addr === "h10e".U & isSlvMode) -> sReg.deltaFinal(55,48),
|
||||
// (addr === "h10f".U & isSlvMode) -> sReg.deltaFinal(63,56),
|
||||
(addr === "h10c".U & isSlvMode) -> sReg.deltaFinal(39,32),
|
||||
(addr === "h10d".U & isSlvMode) -> sReg.deltaFinal(47,40),
|
||||
(addr === "h10e".U & isSlvMode) -> sReg.deltaFinal(55,48),
|
||||
(addr === "h10f".U & isSlvMode) -> sReg.deltaFinal(63,56),
|
||||
|
||||
//主站发送接收时间差
|
||||
(addr === "h110".U ) -> cReg.mstDeltaTime(7,0),
|
||||
@@ -411,13 +411,13 @@ abstract class InterfaceBase extends Module{
|
||||
|
||||
//校准后的时钟
|
||||
(addr === "h118".U ) -> cReg.recoTimeStamp(7,0),
|
||||
(addr === "h119".U ) -> cReg.recoTimeStamp(15,8),
|
||||
(addr === "h11a".U ) -> cReg.recoTimeStamp(23,16),
|
||||
(addr === "h11b".U ) -> cReg.recoTimeStamp(31,24),
|
||||
(addr === "h11c".U ) -> cReg.recoTimeStamp(39,32),
|
||||
(addr === "h11d".U ) -> cReg.recoTimeStamp(47,40),
|
||||
(addr === "h11e".U ) -> cReg.recoTimeStamp(55,48),
|
||||
(addr === "h11f".U ) -> cReg.recoTimeStamp(63,56),
|
||||
(addr === "h119".U ) -> RegEnable(cReg.recoTimeStamp(15,8), isEnR & (addrr === "h118".U)),
|
||||
(addr === "h11a".U ) -> RegEnable(cReg.recoTimeStamp(23,16), isEnR & (addrr === "h118".U)),
|
||||
(addr === "h11b".U ) -> RegEnable(cReg.recoTimeStamp(31,24), isEnR & (addrr === "h118".U)),
|
||||
(addr === "h11c".U ) -> RegEnable(cReg.recoTimeStamp(39,32), isEnR & (addrr === "h118".U)),
|
||||
(addr === "h11d".U ) -> RegEnable(cReg.recoTimeStamp(47,40), isEnR & (addrr === "h118".U)),
|
||||
(addr === "h11e".U ) -> RegEnable(cReg.recoTimeStamp(55,48), isEnR & (addrr === "h118".U)),
|
||||
(addr === "h11f".U ) -> RegEnable(cReg.recoTimeStamp(63,56), isEnR & (addrr === "h118".U)),
|
||||
|
||||
(addr === "h120".U ) -> cReg.syncCfg,
|
||||
|
||||
@@ -963,7 +963,7 @@ trait InterfaceSync{ this: InterfaceBase =>
|
||||
sReg.deltaFinal := io.deltaFinal
|
||||
cReg.recoTimeStamp :=
|
||||
Mux(isMstMode, cReg.timeStamp,
|
||||
RegNext( cReg.timeStamp + Cat( Fill(32, sReg.deltaFinal.extract(31)), sReg.deltaFinal ) )
|
||||
RegNext( cReg.timeStamp + sReg.deltaFinal )
|
||||
)
|
||||
sReg.slvDeltaTime := io.slvDeltaTime
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class MasterParserIO extends Bundle{
|
||||
|
||||
}
|
||||
|
||||
abstract class MasterParserBase extends Module{
|
||||
abstract class MasterParserBase extends Module with RequireAsyncReset{
|
||||
val io: MasterParserIO = IO(new MasterParserIO)
|
||||
|
||||
val txCnt = Reg(UInt(12.W))
|
||||
@@ -167,11 +167,11 @@ abstract class MasterParserBase extends Module{
|
||||
|
||||
txcrc.io.isEnable := io.downOut.fire & txCnt < txLen
|
||||
txcrc.io.dataIn := io.downOut.bits.tdata
|
||||
txcrc.reset := reset.asBool | reqReady
|
||||
txcrc.io.flush := reqReady
|
||||
|
||||
rxcrc.io.isEnable := io.upIn.fire & rxCnt < rxLen
|
||||
rxcrc.io.dataIn := io.upIn.bits.tdata
|
||||
rxcrc.reset := reset.asBool | io.rsp.fire
|
||||
rxcrc.io.flush := io.rsp.fire
|
||||
|
||||
|
||||
|
||||
|
||||
510
src/main/scala/backBoard/shin/MstSlvSwitch.scala
Normal file
510
src/main/scala/backBoard/shin/MstSlvSwitch.scala
Normal file
@@ -0,0 +1,510 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
class TopBase_IO_Bundle extends Bundle{
|
||||
val dDatIn = Input(Bool())
|
||||
val dDatOut = Output(Bool())
|
||||
val uDatIn = Input(Bool())
|
||||
val uDatOut = Output(Bool())
|
||||
|
||||
val iqspi = new QSPIInterfaceIO
|
||||
val ospi = new SSPIInterfaceIO
|
||||
val oqspi = new QSPIInterfaceIO
|
||||
|
||||
val iSync = Output(Vec(4, Bool()))
|
||||
|
||||
val isSoftReset = Output(Bool())
|
||||
|
||||
val interrupt = Output(Bool())
|
||||
|
||||
val latchPin = Input(Vec(2, Bool()))
|
||||
val hwSerial = Input(UInt(48.W))
|
||||
val uniCode = Input(UInt(64.W))
|
||||
|
||||
val pllCtrl = Output(UInt(32.W))
|
||||
val xtal = Output(UInt(12.W))
|
||||
val anamuxSel = Output(UInt(5.W))
|
||||
val ldo2p5 = Output(UInt(8.W))
|
||||
val ldo1p1 = Output(UInt(8.W))
|
||||
val refTop = Output(UInt(3.W))
|
||||
val bias = Output(UInt(2.W))
|
||||
|
||||
val spiSel = Output(UInt(2.W))
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MstSlvSwitchIO extends TopBase_IO_Bundle{
|
||||
|
||||
val downCDROut = Flipped(new CDROutIO)
|
||||
val upCDROut = Flipped(new CDROutIO)
|
||||
val downCDRIn = Flipped(new CDRInIO)
|
||||
val upCDRIn = Flipped(new CDRInIO)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
abstract class MstSlvSwitchBase extends Module with RequireAsyncReset{
|
||||
|
||||
val io: MstSlvSwitchIO = IO(new MstSlvSwitchIO)
|
||||
|
||||
val slaveParser = Module(new SlaveParser )
|
||||
val masterParser = Module(new MasterParser)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
val interface = Module(new Interface)
|
||||
|
||||
interface.io.latchPin := io.latchPin
|
||||
interface.io.uniCode := io.uniCode
|
||||
interface.io.hwSerial := io.hwSerial
|
||||
|
||||
interface.io.intTransEnd(0) := io.downCDRIn.axis.fire & io.downCDRIn.axis.bits.tlast
|
||||
interface.io.intTransEnd(1) := io.downCDROut.axis.fire & io.downCDROut.axis.bits.tlast
|
||||
interface.io.intTransEnd(2) := io.upCDRIn.axis.fire & io.upCDRIn.axis.bits.tlast
|
||||
interface.io.intTransEnd(3) := io.upCDROut.axis.fire & io.upCDROut.axis.bits.tlast
|
||||
|
||||
io.isSoftReset := interface.io.isSoftReset
|
||||
io.interrupt := interface.io.interrupt
|
||||
|
||||
io.ospi <> interface.io.ospi
|
||||
io.iqspi <> interface.io.iqspi
|
||||
io.oqspi <> interface.io.oqspi
|
||||
|
||||
io.iSync := interface.io.sync
|
||||
|
||||
|
||||
io.pllCtrl := interface.io.cReg.pllCtrl
|
||||
io.xtal := interface.io.cReg.xtal
|
||||
io.anamuxSel := interface.io.cReg.anamuxSel
|
||||
io.ldo2p5 := interface.io.cReg.ldo2p5
|
||||
io.ldo1p1 := interface.io.cReg.ldo1p1
|
||||
io.refTop := interface.io.cReg.refTop
|
||||
io.bias := interface.io.cReg.bias
|
||||
|
||||
io.spiSel := interface.io.cReg.spiSel
|
||||
|
||||
val sram = Seq(
|
||||
for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) },
|
||||
)
|
||||
|
||||
|
||||
val smUnit = Seq(
|
||||
Module( new SMUnit(depth = 4) ),
|
||||
Module( new SMUnit(depth = 4) ),
|
||||
Module( new SMUnit(depth = 4) ),
|
||||
Module( new SMUnit(depth = 4) ),
|
||||
Module( new SMUnit(depth = 2) ),
|
||||
Module( new SMUnit(depth = 2) ),
|
||||
Module( new SMUnit(depth = 2) ),
|
||||
Module( new SMUnit(depth = 2) ),
|
||||
)
|
||||
|
||||
val lvdsSMEnq = for( i <- 0 until 4 ) yield WireDefault(false.B); interface.io.lvdsSMEnq := lvdsSMEnq
|
||||
val lvdsSMDeq = for( i <- 0 until 4 ) yield WireDefault(false.B); interface.io.lvdsSMDeq := lvdsSMDeq
|
||||
|
||||
|
||||
smUnit(0).io.enq := lvdsSMEnq(0)
|
||||
smUnit(2).io.enq := lvdsSMEnq(1)
|
||||
smUnit(4).io.enq := lvdsSMEnq(2)
|
||||
smUnit(6).io.enq := lvdsSMEnq(3)
|
||||
|
||||
smUnit(1).io.deq := lvdsSMDeq(0)
|
||||
smUnit(3).io.deq := lvdsSMDeq(1)
|
||||
smUnit(5).io.deq := lvdsSMDeq(2)
|
||||
smUnit(7).io.deq := lvdsSMDeq(3)
|
||||
|
||||
smUnit(0).io.sram_r <> interface.io.sram_r(0)
|
||||
smUnit(2).io.sram_r <> interface.io.sram_r(1)
|
||||
smUnit(4).io.sram_r <> interface.io.sram_r(2)
|
||||
smUnit(6).io.sram_r <> interface.io.sram_r(3)
|
||||
|
||||
smUnit(1).io.sram_w := interface.io.sram_w(0)
|
||||
smUnit(3).io.sram_w := interface.io.sram_w(1)
|
||||
smUnit(5).io.sram_w := interface.io.sram_w(2)
|
||||
smUnit(7).io.sram_w := interface.io.sram_w(3)
|
||||
|
||||
smUnit(0).io.deq := interface.io.dSMdeq(0)
|
||||
smUnit(2).io.deq := interface.io.dSMdeq(1)
|
||||
smUnit(4).io.deq := interface.io.dSMdeq(2)
|
||||
smUnit(6).io.deq := interface.io.dSMdeq(3)
|
||||
|
||||
|
||||
smUnit(1).io.enq := interface.io.uSMenq(0)
|
||||
smUnit(3).io.enq := interface.io.uSMenq(1)
|
||||
smUnit(5).io.enq := interface.io.uSMenq(2)
|
||||
smUnit(7).io.enq := interface.io.uSMenq(3)
|
||||
|
||||
for( i <- 0 until 8 ){
|
||||
interface.io.smUsedDepth(i) := smUnit(i).io.cnt
|
||||
smUnit(i).io.flush := interface.io.isSMReset(i)
|
||||
}
|
||||
|
||||
|
||||
for( i <- 0 until 4 ){
|
||||
for( j <- 0 until 4 ){
|
||||
sram(i)(j).io.clockr := clock.asBool
|
||||
sram(i)(j).io.clockw := clock.asBool
|
||||
|
||||
smUnit(i).io.sram(j).rd.datar := sram(i)(j).io.datar
|
||||
sram(i)(j).io.dataw := smUnit(i).io.sram(j).wr.dataw
|
||||
sram(i)(j).io.addrw := smUnit(i).io.sram(j).wr.addrw
|
||||
sram(i)(j).io.enw := smUnit(i).io.sram(j).wr.enw
|
||||
sram(i)(j).io.addrr := smUnit(i).io.sram(j).rd.addrr
|
||||
sram(i)(j).io.enr := smUnit(i).io.sram(j).rd.enr
|
||||
}
|
||||
}
|
||||
|
||||
for( i <- 4 until 8 ){
|
||||
for( j <- 0 until 2 ){
|
||||
sram(i)(j).io.clockr := clock.asBool
|
||||
sram(i)(j).io.clockw := clock.asBool
|
||||
|
||||
smUnit(i).io.sram(j).rd.datar := sram(i)(j).io.datar
|
||||
sram(i)(j).io.dataw := smUnit(i).io.sram(j).wr.dataw
|
||||
sram(i)(j).io.addrw := smUnit(i).io.sram(j).wr.addrw
|
||||
sram(i)(j).io.enw := smUnit(i).io.sram(j).wr.enw
|
||||
sram(i)(j).io.addrr := smUnit(i).io.sram(j).rd.addrr
|
||||
sram(i)(j).io.enr := smUnit(i).io.sram(j).rd.enr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//default
|
||||
{
|
||||
smUnit(0).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO)
|
||||
smUnit(2).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO)
|
||||
smUnit(4).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO)
|
||||
smUnit(6).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO)
|
||||
|
||||
smUnit(1).io.sram_r.enr := false.B
|
||||
smUnit(3).io.sram_r.enr := false.B
|
||||
smUnit(5).io.sram_r.enr := false.B
|
||||
smUnit(7).io.sram_r.enr := false.B
|
||||
smUnit(1).io.sram_r.addrr := 0.U
|
||||
smUnit(3).io.sram_r.addrr := 0.U
|
||||
smUnit(5).io.sram_r.addrr := 0.U
|
||||
smUnit(7).io.sram_r.addrr := 0.U
|
||||
|
||||
slaveParser.io.sram_r(0).datar := 0.U
|
||||
slaveParser.io.sram_r(1).datar := 0.U
|
||||
slaveParser.io.sram_r(2).datar := 0.U
|
||||
slaveParser.io.sram_r(3).datar := 0.U
|
||||
masterParser.io.sram_r.datar := 0.U
|
||||
|
||||
io.downCDRIn.axis.ready := false.B
|
||||
slaveParser.io.downIn.valid := false.B
|
||||
slaveParser.io.downIn.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
|
||||
slaveParser.io.downOut.ready := false.B
|
||||
masterParser.io.downOut.ready := false.B
|
||||
io.downCDROut.axis.valid := false.B
|
||||
io.downCDROut.axis.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
|
||||
io.upCDRIn.axis.ready := false.B
|
||||
slaveParser.io.upIn.valid := false.B
|
||||
slaveParser.io.upIn.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
masterParser.io.upIn.valid := false.B
|
||||
masterParser.io.upIn.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
|
||||
slaveParser.io.upOut.ready := false.B
|
||||
io.upCDROut.axis.valid := false.B
|
||||
io.upCDROut.axis.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
|
||||
interface.io.mstDeltaTime := 0.U
|
||||
|
||||
interface.io.slvDeltaTime := 0.U
|
||||
interface.io.deltaFinal := 0.U
|
||||
|
||||
interface.io.intMstTrig(0) := false.B
|
||||
interface.io.intMstTrig(1) := false.B
|
||||
|
||||
interface.io.intSlvTrig(0) := false.B
|
||||
interface.io.intSlvTrig(1) := false.B
|
||||
interface.io.intSlvTrig(2) := false.B
|
||||
interface.io.intSlvTrig(3) := false.B
|
||||
interface.io.intSlvTrig(4) := false.B
|
||||
interface.io.intSlvTrig(5) := false.B
|
||||
interface.io.intSlvTrig(6) := false.B
|
||||
interface.io.intSlvTrig(7) := false.B
|
||||
|
||||
interface.io.intHWTrig(0) := false.B
|
||||
interface.io.intHWTrig(1) := false.B
|
||||
|
||||
interface.io.downRecStat := 0.U.asTypeOf(new Stat_IO_Bundle)
|
||||
interface.io.upRecStat := 0.U.asTypeOf(new Stat_IO_Bundle)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait MstSlvSwitchMaster{ this: MstSlvSwitchBase =>
|
||||
|
||||
when( interface.io.cReg.modeSel === true.B ){
|
||||
masterParser.io.downOut <> io.downCDROut.axis
|
||||
masterParser.io.upIn <> io.upCDRIn.axis
|
||||
}
|
||||
|
||||
when( interface.io.cReg.modeSel === true.B ){
|
||||
|
||||
when( interface.io.txReq.bits.rxSM === 0.U ){
|
||||
smUnit(0).io.sram_w := masterParser.io.sram_w
|
||||
lvdsSMEnq(0) := masterParser.io.rxEnq
|
||||
} .elsewhen( interface.io.txReq.bits.rxSM === 1.U ){
|
||||
smUnit(2).io.sram_w := masterParser.io.sram_w
|
||||
lvdsSMEnq(1) := masterParser.io.rxEnq
|
||||
} .elsewhen( interface.io.txReq.bits.rxSM === 2.U ){
|
||||
smUnit(4).io.sram_w := masterParser.io.sram_w
|
||||
lvdsSMEnq(2) := masterParser.io.rxEnq
|
||||
} .elsewhen( interface.io.txReq.bits.rxSM === 3.U ){
|
||||
smUnit(6).io.sram_w := masterParser.io.sram_w
|
||||
lvdsSMEnq(3) := masterParser.io.rxEnq
|
||||
}
|
||||
|
||||
when( interface.io.txReq.bits.txSM === 0.U ){
|
||||
smUnit(1).io.sram_r <> masterParser.io.sram_r
|
||||
lvdsSMDeq(0) := masterParser.io.txDeq
|
||||
} .elsewhen( interface.io.txReq.bits.txSM === 1.U ){
|
||||
smUnit(3).io.sram_r <> masterParser.io.sram_r
|
||||
lvdsSMDeq(1) := masterParser.io.txDeq
|
||||
} .elsewhen( interface.io.txReq.bits.txSM === 2.U ){
|
||||
smUnit(5).io.sram_r <> masterParser.io.sram_r
|
||||
lvdsSMDeq(2) := masterParser.io.txDeq
|
||||
} .elsewhen( interface.io.txReq.bits.txSM === 3.U ){
|
||||
smUnit(7).io.sram_r <> masterParser.io.sram_r
|
||||
lvdsSMDeq(3) := masterParser.io.txDeq
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface.io.mstDeltaTime := masterParser.io.deltaTimeStamp
|
||||
interface.io.intMstTrig(0) := masterParser.io.txDeq
|
||||
interface.io.intMstTrig(1) := masterParser.io.rxEnq
|
||||
|
||||
interface.io.downRecStat := 0.U.asTypeOf(new Stat_IO_Bundle)
|
||||
interface.io.upRecStat := masterParser.io.upRecStat
|
||||
|
||||
}
|
||||
|
||||
masterParser.io.req := interface.io.txReq.valid
|
||||
// masterParser.io.req.bits.txLength := interface.io.txReq.bits.txLength
|
||||
|
||||
// io.rsp := masterParser.io.rsp
|
||||
|
||||
masterParser.io.cReg := interface.io.cReg
|
||||
masterParser.io.mReg := interface.io.mReg
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait MstSlvSwitchSlave{ this: MstSlvSwitchBase =>
|
||||
|
||||
when( interface.io.cReg.modeSel === false.B ){
|
||||
slaveParser.io.downIn <> io.downCDRIn.axis
|
||||
io.downCDROut.axis <> slaveParser.io.downOut
|
||||
slaveParser.io.upIn <> io.upCDRIn.axis
|
||||
io.upCDROut.axis <> slaveParser.io.upOut
|
||||
}
|
||||
|
||||
slaveParser.io.cReg := interface.io.cReg
|
||||
slaveParser.io.sReg := interface.io.sReg
|
||||
|
||||
when( interface.io.cReg.modeSel === false.B ){
|
||||
smUnit(0).io.sram_w := slaveParser.io.sram_w(0)
|
||||
smUnit(2).io.sram_w := slaveParser.io.sram_w(1)
|
||||
smUnit(4).io.sram_w := slaveParser.io.sram_w(2)
|
||||
smUnit(6).io.sram_w := slaveParser.io.sram_w(3)
|
||||
|
||||
smUnit(1).io.sram_r <> slaveParser.io.sram_r(0)
|
||||
smUnit(3).io.sram_r <> slaveParser.io.sram_r(1)
|
||||
smUnit(5).io.sram_r <> slaveParser.io.sram_r(2)
|
||||
smUnit(7).io.sram_r <> slaveParser.io.sram_r(3)
|
||||
|
||||
lvdsSMEnq(0) := slaveParser.io.dSMenq(0)
|
||||
lvdsSMEnq(1) := slaveParser.io.dSMenq(1)
|
||||
lvdsSMEnq(2) := slaveParser.io.dSMenq(2)
|
||||
lvdsSMEnq(3) := slaveParser.io.dSMenq(3)
|
||||
|
||||
lvdsSMDeq(0) := slaveParser.io.uSMdeq(0)
|
||||
lvdsSMDeq(1) := slaveParser.io.uSMdeq(1)
|
||||
lvdsSMDeq(2) := slaveParser.io.uSMdeq(2)
|
||||
lvdsSMDeq(3) := slaveParser.io.uSMdeq(3)
|
||||
|
||||
interface.io.mstDeltaTime := slaveParser.io.mstDeltaTimeStamp
|
||||
interface.io.slvDeltaTime := slaveParser.io.slvDeltaTime
|
||||
interface.io.deltaFinal := slaveParser.io.deltaFinal
|
||||
|
||||
interface.io.intSlvTrig(0) := slaveParser.io.dSMenq(0)
|
||||
interface.io.intSlvTrig(1) := slaveParser.io.uSMdeq(0)
|
||||
interface.io.intSlvTrig(2) := slaveParser.io.dSMenq(1)
|
||||
interface.io.intSlvTrig(3) := slaveParser.io.uSMdeq(1)
|
||||
interface.io.intSlvTrig(4) := slaveParser.io.dSMenq(2)
|
||||
interface.io.intSlvTrig(5) := slaveParser.io.uSMdeq(2)
|
||||
interface.io.intSlvTrig(6) := slaveParser.io.dSMenq(3)
|
||||
interface.io.intSlvTrig(7) := slaveParser.io.uSMdeq(3)
|
||||
|
||||
interface.io.intHWTrig(0) := slaveParser.io.intHWTrig(0)
|
||||
interface.io.intHWTrig(1) := slaveParser.io.intHWTrig(1)
|
||||
|
||||
|
||||
interface.io.downRecStat := slaveParser.io.downRecStat
|
||||
interface.io.upRecStat := slaveParser.io.upRecStat
|
||||
|
||||
}
|
||||
|
||||
slaveParser.io.intHWClr(0) := interface.io.intHWTrig(0) & interface.io.intHWClr(0)
|
||||
slaveParser.io.intHWClr(1) := interface.io.intHWTrig(1) & interface.io.intHWClr(1)
|
||||
io.downCDRIn.flush := RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) )
|
||||
io.upCDRIn.flush := RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) )
|
||||
io.downCDROut.flush := RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) )
|
||||
io.upCDROut.flush := RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) )
|
||||
|
||||
interface.io.lvds <> slaveParser.io.lvds
|
||||
|
||||
interface.io.localDevIndex := slaveParser.io.localDevIndex
|
||||
|
||||
//从站链路寄存器
|
||||
// interface.io.isDevOnLeft := slaveParser.io.isDevOnLeft
|
||||
// interface.io.isDevOnLeftModify := slaveParser.io.isDevOnLeftModify
|
||||
// interface.io.indexOfLeftDev := slaveParser.io.indexOfLeftDev
|
||||
interface.io.isDevOnRight := slaveParser.io.isDevOnRight
|
||||
interface.io.isDevOnRightModify := slaveParser.io.isDevOnRightModify
|
||||
interface.io.indexOfRightDev := slaveParser.io.indexOfRightDev
|
||||
}
|
||||
|
||||
|
||||
trait MstSlvSwitchWatchDog{ this: MstSlvSwitchBase =>
|
||||
|
||||
//看门狗1~16,SM监控
|
||||
val isWdtSMEnable = for( _ <- 0 until 16 ) yield { RegInit(false.B) }
|
||||
val wdtSMCnt = for( _ <- 0 until 16 ) yield { Reg(UInt(32.W)) }
|
||||
|
||||
for( i <- 0 until 8 ){
|
||||
when( smUnit(i).io.enq ){
|
||||
isWdtSMEnable(2*i) := false.B
|
||||
} .elsewhen( ~isWdtSMEnable(2*i) & smUnit(i).io.sram_w.enw & interface.io.cReg.wdtEnable.extract(i+1) ){
|
||||
isWdtSMEnable(2*i) := true.B
|
||||
}
|
||||
|
||||
when( smUnit(i).io.deq ){
|
||||
isWdtSMEnable(2*i + 1) := false.B
|
||||
} .elsewhen( ~isWdtSMEnable(2*i + 1) & smUnit(i).io.sram_r.enr & interface.io.cReg.wdtEnable.extract(i+1) ){
|
||||
isWdtSMEnable(2*i + 1) := true.B
|
||||
}
|
||||
}
|
||||
|
||||
for( i <- 0 until 16 ){
|
||||
when( isWdtSMEnable(i) & (wdtSMCnt(i) < interface.io.cReg.wdtTarCnt(i+1)) ){
|
||||
wdtSMCnt(i) := wdtSMCnt(i) + 1.U
|
||||
} .elsewhen( ~isWdtSMEnable(i) || (wdtSMCnt(i) >= interface.io.cReg.wdtTarCnt(i+1)) ){
|
||||
wdtSMCnt(i) := 0.U
|
||||
}
|
||||
|
||||
// assert( wdtSMCnt(i) <= interface.io.cReg.wdtTarCnt(i+1), s"Assert Failed! wdtSMCnt($i) is larger than wdtTarCnt, Special situation?" )
|
||||
|
||||
interface.io.wdtTrigger(i+1) := wdtSMCnt(i) === interface.io.cReg.wdtTarCnt(i+1)
|
||||
}
|
||||
|
||||
//看门狗0 发送后回包是否超时
|
||||
val isWdtRec2RtnEnable = RegInit(false.B)
|
||||
val wdtRec2RtnCnt = Reg(UInt(32.W))
|
||||
|
||||
when(
|
||||
(io.upCDRIn.axis.fire & io.upCDRIn.axis.bits.tlast) |
|
||||
~interface.io.cReg.wdtEnable.extract(0)
|
||||
){
|
||||
isWdtRec2RtnEnable := false.B
|
||||
} .elsewhen( ~isWdtRec2RtnEnable & io.downCDROut.axis.fire & interface.io.cReg.wdtEnable.extract(0) ){
|
||||
isWdtRec2RtnEnable := true.B
|
||||
}
|
||||
|
||||
when( isWdtRec2RtnEnable & (wdtRec2RtnCnt < interface.io.cReg.wdtTarCnt(0)) ){
|
||||
wdtRec2RtnCnt := wdtRec2RtnCnt + 1.U
|
||||
} .elsewhen( ~isWdtRec2RtnEnable || (wdtRec2RtnCnt >= interface.io.cReg.wdtTarCnt(0)) ){
|
||||
wdtRec2RtnCnt := 0.U
|
||||
}
|
||||
|
||||
// assert( wdtRecCnt < interface.io.cReg.wdtTarCnt(0), "Assert Failed! wdtRecCnt is larger than wdtTarCnt, Special situation?" )
|
||||
|
||||
interface.io.wdtTrigger(0) := wdtRec2RtnCnt === interface.io.cReg.wdtTarCnt(0)
|
||||
|
||||
//看门狗17
|
||||
val wdtRec2RecCnt = Reg(UInt(32.W))
|
||||
|
||||
when( interface.io.cReg.wdtEnable.extract(17) & (wdtRec2RecCnt < interface.io.cReg.wdtTarCnt(17)) ){
|
||||
wdtRec2RecCnt := wdtRec2RecCnt + 1.U
|
||||
} .elsewhen(
|
||||
~interface.io.cReg.wdtEnable.extract(17) ||
|
||||
io.downCDRIn.axis.fire ||
|
||||
(wdtRec2RecCnt >= interface.io.cReg.wdtTarCnt(17))
|
||||
){
|
||||
wdtRec2RecCnt := 0.U
|
||||
}
|
||||
|
||||
interface.io.wdtTrigger(17) := wdtRec2RecCnt === interface.io.cReg.wdtTarCnt(17)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MstSlvSwitch extends MstSlvSwitchBase
|
||||
with MstSlvSwitchMaster
|
||||
with MstSlvSwitchSlave
|
||||
with MstSlvSwitchWatchDog{
|
||||
|
||||
|
||||
|
||||
when( interface.io.cReg.modeSel === false.B ){ //slave
|
||||
when( (slaveParser.io.intHWTrig(0) | slaveParser.io.intHWTrig(1)) | interface.io.isPoReset ){ //硬件错误
|
||||
io.downCDRIn.serDat := false.B
|
||||
io.upCDRIn.serDat := false.B
|
||||
when( slaveParser.io.isLoop ){ //回环
|
||||
io.dDatOut := false.B
|
||||
io.uDatOut := io.dDatIn
|
||||
} .otherwise{ //非回环
|
||||
io.dDatOut := io.dDatIn
|
||||
io.uDatOut := io.uDatIn
|
||||
}
|
||||
} .otherwise{ //无硬件错误
|
||||
when( slaveParser.io.isLoop ){ //回环
|
||||
io.downCDRIn.serDat := io.dDatIn
|
||||
io.upCDRIn.serDat := io.downCDROut.serDat
|
||||
io.dDatOut := false.B
|
||||
io.uDatOut := io.upCDROut.serDat
|
||||
} .otherwise{ //非回环
|
||||
io.downCDRIn.serDat := io.dDatIn
|
||||
io.upCDRIn.serDat := io.uDatIn
|
||||
io.dDatOut := io.downCDROut.serDat
|
||||
io.uDatOut := io.upCDROut.serDat
|
||||
}
|
||||
}
|
||||
} .otherwise{ //master
|
||||
io.downCDRIn.serDat := false.B
|
||||
io.upCDRIn.serDat := io.uDatIn
|
||||
io.dDatOut := io.downCDROut.serDat
|
||||
io.uDatOut := false.B
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -33,9 +33,11 @@ class SMUnitIO(depth: Int) extends Bundle {
|
||||
val sram = Flipped(Vec(depth, new SRAM2kIO))
|
||||
val cnt = Output(UInt(8.W))
|
||||
|
||||
val flush = Input(Bool())
|
||||
|
||||
}
|
||||
|
||||
abstract class SMUnitBase(depth: Int = 4) extends Module {
|
||||
abstract class SMUnitBase(depth: Int = 4) extends Module with RequireAsyncReset{
|
||||
val io: SMUnitIO = IO(new SMUnitIO(depth))
|
||||
|
||||
|
||||
@@ -43,18 +45,19 @@ abstract class SMUnitBase(depth: Int = 4) extends Module {
|
||||
val rPtr = RegInit(0.U((log2Ceil(depth)+1).W))
|
||||
|
||||
val isFull = (wPtr ^ rPtr) === (1.U << log2Ceil(depth))
|
||||
// ( wPtr.extract(2) =/= rPtr.extract(2) ) & ( wPtr(1,0) === rPtr(1,0) )
|
||||
|
||||
|
||||
val isEmpty = ( wPtr === rPtr )
|
||||
|
||||
|
||||
when( io.enq & ~isFull ){
|
||||
when(io.flush){
|
||||
wPtr := 0.U
|
||||
} .elsewhen( io.enq & ~isFull ){
|
||||
wPtr := wPtr + 1.U
|
||||
// assert( ~isFull)
|
||||
}
|
||||
|
||||
when( io.deq & ~isEmpty ){
|
||||
when(io.flush){
|
||||
rPtr := 0.U
|
||||
} .elsewhen( io.deq & ~isEmpty ){
|
||||
rPtr := rPtr + 1.U
|
||||
// assert( ~isEmpty )
|
||||
}
|
||||
@@ -87,7 +90,9 @@ abstract class SMUnitBase(depth: Int = 4) extends Module {
|
||||
|
||||
val cnt = RegInit(0.U((log2Ceil(depth+1)).W)); io.cnt := cnt
|
||||
|
||||
when( io.enq & ~isFull ){
|
||||
when( io.flush ){
|
||||
cnt := 0.U
|
||||
} .elsewhen( io.enq & ~isFull ){
|
||||
cnt := cnt + 1.U
|
||||
assert(cnt =/= depth.U)
|
||||
} .elsewhen( io.deq & ~isEmpty ){
|
||||
|
||||
@@ -3,59 +3,19 @@ package BACK
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import chisel3.experimental.dataview._
|
||||
|
||||
class ShinTopIO extends Bundle{
|
||||
|
||||
val dDatIn = Input(Bool())
|
||||
val dDatOut = Output(Bool())
|
||||
val uDatIn = Input(Bool())
|
||||
val uDatOut = Output(Bool())
|
||||
|
||||
class ShinTopIO extends TopBase_IO_Bundle{
|
||||
val multiCLK = Input(Vec(16, Bool()))
|
||||
|
||||
val iqspi = new QSPIInterfaceIO
|
||||
val ospi = new SSPIInterfaceIO
|
||||
val oqspi = new QSPIInterfaceIO
|
||||
|
||||
// val rsp = Valid(new Bundle{
|
||||
// val isError = Bool()
|
||||
// })
|
||||
|
||||
val iSync = Output(Vec(4, Bool()))
|
||||
val oSync = Output(Vec(4, Bool()))
|
||||
|
||||
val isSoftReset = Output(Bool())
|
||||
val ledTest = Output(UInt(8.W))
|
||||
|
||||
val interrupt = Output(Bool())
|
||||
|
||||
val latchPin = Input(Vec(2, Bool()))
|
||||
val hwSerial = Input(UInt(48.W))
|
||||
val uniCode = Input(UInt(64.W))
|
||||
|
||||
val pllCtrl = Output(UInt(32.W))
|
||||
val xtal = Output(UInt(12.W))
|
||||
val anamuxSel = Output(UInt(5.W))
|
||||
val ldo2p5 = Output(UInt(8.W))
|
||||
val ldo1p1 = Output(UInt(8.W))
|
||||
val refTop = Output(UInt(3.W))
|
||||
val bias = Output(UInt(2.W))
|
||||
|
||||
val spiSel = Output(UInt(2.W))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
abstract class ShinTopBase extends Module{
|
||||
|
||||
class ShinTop extends Module with RequireAsyncReset{
|
||||
val io: ShinTopIO = IO(new ShinTopIO)
|
||||
|
||||
val slaveParser = Module(new SlaveParser )
|
||||
val masterParser = Module(new MasterParser)
|
||||
|
||||
val mstSlvSwitch = Module(new MstSlvSwitch)
|
||||
val downCDROut = Module(new CDROut)
|
||||
val upCDROut = Module(new CDROut)
|
||||
val downCDRIn = Module(new MPCDRIn)
|
||||
val upCDRIn = Module(new MPCDRIn)
|
||||
|
||||
@@ -64,452 +24,17 @@ abstract class ShinTopBase extends Module{
|
||||
upCDRIn.multiCLK := io.multiCLK
|
||||
|
||||
|
||||
val downCDROut = Module(new CDROut)
|
||||
val upCDROut = Module(new CDROut)
|
||||
downCDROut.io <> mstSlvSwitch.io.downCDROut
|
||||
upCDROut.io <> mstSlvSwitch.io.upCDROut
|
||||
downCDRIn.io <> mstSlvSwitch.io.downCDRIn
|
||||
upCDRIn.io <> mstSlvSwitch.io.upCDRIn
|
||||
|
||||
val interface = Module(new Interface)
|
||||
io.viewAsSupertype(new TopBase_IO_Bundle) <> mstSlvSwitch.io.viewAsSupertype(new TopBase_IO_Bundle)
|
||||
|
||||
interface.io.latchPin := io.latchPin
|
||||
interface.io.uniCode := io.uniCode
|
||||
interface.io.hwSerial := io.hwSerial
|
||||
|
||||
interface.io.intTransEnd(0) := downCDRIn.io.axis.fire & downCDRIn.io.axis.bits.tlast
|
||||
interface.io.intTransEnd(1) := downCDROut.io.axis.fire & downCDROut.io.axis.bits.tlast
|
||||
interface.io.intTransEnd(2) := upCDRIn.io.axis.fire & upCDRIn.io.axis.bits.tlast
|
||||
interface.io.intTransEnd(3) := upCDROut.io.axis.fire & upCDROut.io.axis.bits.tlast
|
||||
|
||||
io.ledTest := RegNext( Cat(slaveParser.io.intHWTrig(0), slaveParser.io.intHWTrig(1)) )
|
||||
|
||||
io.isSoftReset := interface.io.isSoftReset
|
||||
io.interrupt := interface.io.interrupt
|
||||
|
||||
io.ospi <> interface.io.ospi
|
||||
io.iqspi <> interface.io.iqspi
|
||||
io.oqspi <> interface.io.oqspi
|
||||
|
||||
io.iSync := interface.io.sync
|
||||
io.oSync := interface.io.sync
|
||||
|
||||
io.pllCtrl := interface.io.cReg.pllCtrl
|
||||
io.xtal := interface.io.cReg.xtal
|
||||
io.anamuxSel := interface.io.cReg.anamuxSel
|
||||
io.ldo2p5 := interface.io.cReg.ldo2p5
|
||||
io.ldo1p1 := interface.io.cReg.ldo1p1
|
||||
io.refTop := interface.io.cReg.refTop
|
||||
io.bias := interface.io.cReg.bias
|
||||
|
||||
io.spiSel := interface.io.cReg.spiSel
|
||||
|
||||
val sram = Seq(
|
||||
for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 4 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) },
|
||||
for( _ <- 0 until 2 ) yield { Module(new ShareSRAM2k) },
|
||||
)
|
||||
|
||||
|
||||
val smUnit = Seq(
|
||||
Module( new SMUnit(depth = 4) ),
|
||||
Module( new SMUnit(depth = 4) ),
|
||||
Module( new SMUnit(depth = 4) ),
|
||||
Module( new SMUnit(depth = 4) ),
|
||||
Module( new SMUnit(depth = 2) ),
|
||||
Module( new SMUnit(depth = 2) ),
|
||||
Module( new SMUnit(depth = 2) ),
|
||||
Module( new SMUnit(depth = 2) ),
|
||||
)
|
||||
|
||||
val lvdsSMEnq = for( i <- 0 until 4 ) yield WireDefault(false.B); interface.io.lvdsSMEnq := lvdsSMEnq
|
||||
val lvdsSMDeq = for( i <- 0 until 4 ) yield WireDefault(false.B); interface.io.lvdsSMDeq := lvdsSMDeq
|
||||
|
||||
|
||||
smUnit(0).io.enq := lvdsSMEnq(0)
|
||||
smUnit(2).io.enq := lvdsSMEnq(1)
|
||||
smUnit(4).io.enq := lvdsSMEnq(2)
|
||||
smUnit(6).io.enq := lvdsSMEnq(3)
|
||||
|
||||
smUnit(1).io.deq := lvdsSMDeq(0)
|
||||
smUnit(3).io.deq := lvdsSMDeq(1)
|
||||
smUnit(5).io.deq := lvdsSMDeq(2)
|
||||
smUnit(7).io.deq := lvdsSMDeq(3)
|
||||
|
||||
smUnit(0).io.sram_r <> interface.io.sram_r(0)
|
||||
smUnit(2).io.sram_r <> interface.io.sram_r(1)
|
||||
smUnit(4).io.sram_r <> interface.io.sram_r(2)
|
||||
smUnit(6).io.sram_r <> interface.io.sram_r(3)
|
||||
|
||||
smUnit(1).io.sram_w := interface.io.sram_w(0)
|
||||
smUnit(3).io.sram_w := interface.io.sram_w(1)
|
||||
smUnit(5).io.sram_w := interface.io.sram_w(2)
|
||||
smUnit(7).io.sram_w := interface.io.sram_w(3)
|
||||
|
||||
smUnit(0).io.deq := interface.io.dSMdeq(0)
|
||||
smUnit(2).io.deq := interface.io.dSMdeq(1)
|
||||
smUnit(4).io.deq := interface.io.dSMdeq(2)
|
||||
smUnit(6).io.deq := interface.io.dSMdeq(3)
|
||||
|
||||
|
||||
smUnit(1).io.enq := interface.io.uSMenq(0)
|
||||
smUnit(3).io.enq := interface.io.uSMenq(1)
|
||||
smUnit(5).io.enq := interface.io.uSMenq(2)
|
||||
smUnit(7).io.enq := interface.io.uSMenq(3)
|
||||
|
||||
for( i <- 0 until 8 ){
|
||||
interface.io.smUsedDepth(i) := smUnit(i).io.cnt
|
||||
smUnit(i).reset := reset.asBool | interface.io.isSMReset(i)
|
||||
}
|
||||
|
||||
|
||||
for( i <- 0 until 4 ){
|
||||
for( j <- 0 until 4 ){
|
||||
sram(i)(j).io.clockr := clock.asBool
|
||||
sram(i)(j).io.clockw := clock.asBool
|
||||
|
||||
smUnit(i).io.sram(j).rd.datar := sram(i)(j).io.datar
|
||||
sram(i)(j).io.dataw := smUnit(i).io.sram(j).wr.dataw
|
||||
sram(i)(j).io.addrw := smUnit(i).io.sram(j).wr.addrw
|
||||
sram(i)(j).io.enw := smUnit(i).io.sram(j).wr.enw
|
||||
sram(i)(j).io.addrr := smUnit(i).io.sram(j).rd.addrr
|
||||
sram(i)(j).io.enr := smUnit(i).io.sram(j).rd.enr
|
||||
}
|
||||
}
|
||||
|
||||
for( i <- 4 until 8 ){
|
||||
for( j <- 0 until 2 ){
|
||||
sram(i)(j).io.clockr := clock.asBool
|
||||
sram(i)(j).io.clockw := clock.asBool
|
||||
|
||||
smUnit(i).io.sram(j).rd.datar := sram(i)(j).io.datar
|
||||
sram(i)(j).io.dataw := smUnit(i).io.sram(j).wr.dataw
|
||||
sram(i)(j).io.addrw := smUnit(i).io.sram(j).wr.addrw
|
||||
sram(i)(j).io.enw := smUnit(i).io.sram(j).wr.enw
|
||||
sram(i)(j).io.addrr := smUnit(i).io.sram(j).rd.addrr
|
||||
sram(i)(j).io.enr := smUnit(i).io.sram(j).rd.enr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//default
|
||||
{
|
||||
smUnit(0).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO)
|
||||
smUnit(2).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO)
|
||||
smUnit(4).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO)
|
||||
smUnit(6).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO)
|
||||
|
||||
smUnit(1).io.sram_r.enr := false.B
|
||||
smUnit(3).io.sram_r.enr := false.B
|
||||
smUnit(5).io.sram_r.enr := false.B
|
||||
smUnit(7).io.sram_r.enr := false.B
|
||||
smUnit(1).io.sram_r.addrr := 0.U
|
||||
smUnit(3).io.sram_r.addrr := 0.U
|
||||
smUnit(5).io.sram_r.addrr := 0.U
|
||||
smUnit(7).io.sram_r.addrr := 0.U
|
||||
|
||||
slaveParser.io.sram_r(0).datar := 0.U
|
||||
slaveParser.io.sram_r(1).datar := 0.U
|
||||
slaveParser.io.sram_r(2).datar := 0.U
|
||||
slaveParser.io.sram_r(3).datar := 0.U
|
||||
masterParser.io.sram_r.datar := 0.U
|
||||
|
||||
downCDRIn.io.axis.ready := false.B
|
||||
slaveParser.io.downIn.valid := false.B
|
||||
slaveParser.io.downIn.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
|
||||
slaveParser.io.downOut.ready := false.B
|
||||
masterParser.io.downOut.ready := false.B
|
||||
downCDROut.io.axis.valid := false.B
|
||||
downCDROut.io.axis.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
|
||||
upCDRIn.io.axis.ready := false.B
|
||||
slaveParser.io.upIn.valid := false.B
|
||||
slaveParser.io.upIn.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
masterParser.io.upIn.valid := false.B
|
||||
masterParser.io.upIn.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
|
||||
slaveParser.io.upOut.ready := false.B
|
||||
upCDROut.io.axis.valid := false.B
|
||||
upCDROut.io.axis.bits := 0.U.asTypeOf(new AXIS_Bundle(8))
|
||||
|
||||
interface.io.mstDeltaTime := 0.U
|
||||
|
||||
interface.io.slvDeltaTime := 0.U
|
||||
interface.io.deltaFinal := 0.U
|
||||
|
||||
interface.io.intMstTrig(0) := false.B
|
||||
interface.io.intMstTrig(1) := false.B
|
||||
|
||||
interface.io.intSlvTrig(0) := false.B
|
||||
interface.io.intSlvTrig(1) := false.B
|
||||
interface.io.intSlvTrig(2) := false.B
|
||||
interface.io.intSlvTrig(3) := false.B
|
||||
interface.io.intSlvTrig(4) := false.B
|
||||
interface.io.intSlvTrig(5) := false.B
|
||||
interface.io.intSlvTrig(6) := false.B
|
||||
interface.io.intSlvTrig(7) := false.B
|
||||
|
||||
interface.io.intHWTrig(0) := false.B
|
||||
interface.io.intHWTrig(1) := false.B
|
||||
|
||||
interface.io.downRecStat := 0.U.asTypeOf(new Stat_IO_Bundle)
|
||||
interface.io.upRecStat := 0.U.asTypeOf(new Stat_IO_Bundle)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait ShinTopMaster{ this: ShinTopBase =>
|
||||
|
||||
when( interface.io.cReg.modeSel === true.B ){
|
||||
masterParser.io.downOut <> downCDROut.io.axis
|
||||
masterParser.io.upIn <> upCDRIn.io.axis
|
||||
}
|
||||
|
||||
when( interface.io.cReg.modeSel === true.B ){
|
||||
|
||||
when( interface.io.txReq.bits.rxSM === 0.U ){
|
||||
smUnit(0).io.sram_w := masterParser.io.sram_w
|
||||
lvdsSMEnq(0) := masterParser.io.rxEnq
|
||||
} .elsewhen( interface.io.txReq.bits.rxSM === 1.U ){
|
||||
smUnit(2).io.sram_w := masterParser.io.sram_w
|
||||
lvdsSMEnq(1) := masterParser.io.rxEnq
|
||||
} .elsewhen( interface.io.txReq.bits.rxSM === 2.U ){
|
||||
smUnit(4).io.sram_w := masterParser.io.sram_w
|
||||
lvdsSMEnq(2) := masterParser.io.rxEnq
|
||||
} .elsewhen( interface.io.txReq.bits.rxSM === 3.U ){
|
||||
smUnit(6).io.sram_w := masterParser.io.sram_w
|
||||
lvdsSMEnq(3) := masterParser.io.rxEnq
|
||||
}
|
||||
|
||||
when( interface.io.txReq.bits.txSM === 0.U ){
|
||||
smUnit(1).io.sram_r <> masterParser.io.sram_r
|
||||
lvdsSMDeq(0) := masterParser.io.txDeq
|
||||
} .elsewhen( interface.io.txReq.bits.txSM === 1.U ){
|
||||
smUnit(3).io.sram_r <> masterParser.io.sram_r
|
||||
lvdsSMDeq(1) := masterParser.io.txDeq
|
||||
} .elsewhen( interface.io.txReq.bits.txSM === 2.U ){
|
||||
smUnit(5).io.sram_r <> masterParser.io.sram_r
|
||||
lvdsSMDeq(2) := masterParser.io.txDeq
|
||||
} .elsewhen( interface.io.txReq.bits.txSM === 3.U ){
|
||||
smUnit(7).io.sram_r <> masterParser.io.sram_r
|
||||
lvdsSMDeq(3) := masterParser.io.txDeq
|
||||
}
|
||||
|
||||
|
||||
|
||||
interface.io.mstDeltaTime := masterParser.io.deltaTimeStamp
|
||||
interface.io.intMstTrig(0) := masterParser.io.txDeq
|
||||
interface.io.intMstTrig(1) := masterParser.io.rxEnq
|
||||
|
||||
interface.io.downRecStat := 0.U.asTypeOf(new Stat_IO_Bundle)
|
||||
interface.io.upRecStat := masterParser.io.upRecStat
|
||||
|
||||
}
|
||||
|
||||
masterParser.io.req := interface.io.txReq.valid
|
||||
// masterParser.io.req.bits.txLength := interface.io.txReq.bits.txLength
|
||||
|
||||
// io.rsp := masterParser.io.rsp
|
||||
|
||||
masterParser.io.cReg := interface.io.cReg
|
||||
masterParser.io.mReg := interface.io.mReg
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait ShinTopSlave{ this: ShinTopBase =>
|
||||
|
||||
when( interface.io.cReg.modeSel === false.B ){
|
||||
slaveParser.io.downIn <> downCDRIn.io.axis
|
||||
downCDROut.io.axis <> slaveParser.io.downOut
|
||||
slaveParser.io.upIn <> upCDRIn.io.axis
|
||||
upCDROut.io.axis <> slaveParser.io.upOut
|
||||
}
|
||||
|
||||
slaveParser.io.cReg := interface.io.cReg
|
||||
slaveParser.io.sReg := interface.io.sReg
|
||||
|
||||
when( interface.io.cReg.modeSel === false.B ){
|
||||
smUnit(0).io.sram_w := slaveParser.io.sram_w(0)
|
||||
smUnit(2).io.sram_w := slaveParser.io.sram_w(1)
|
||||
smUnit(4).io.sram_w := slaveParser.io.sram_w(2)
|
||||
smUnit(6).io.sram_w := slaveParser.io.sram_w(3)
|
||||
|
||||
smUnit(1).io.sram_r <> slaveParser.io.sram_r(0)
|
||||
smUnit(3).io.sram_r <> slaveParser.io.sram_r(1)
|
||||
smUnit(5).io.sram_r <> slaveParser.io.sram_r(2)
|
||||
smUnit(7).io.sram_r <> slaveParser.io.sram_r(3)
|
||||
|
||||
lvdsSMEnq(0) := slaveParser.io.dSMenq(0)
|
||||
lvdsSMEnq(1) := slaveParser.io.dSMenq(1)
|
||||
lvdsSMEnq(2) := slaveParser.io.dSMenq(2)
|
||||
lvdsSMEnq(3) := slaveParser.io.dSMenq(3)
|
||||
|
||||
lvdsSMDeq(0) := slaveParser.io.uSMdeq(0)
|
||||
lvdsSMDeq(1) := slaveParser.io.uSMdeq(1)
|
||||
lvdsSMDeq(2) := slaveParser.io.uSMdeq(2)
|
||||
lvdsSMDeq(3) := slaveParser.io.uSMdeq(3)
|
||||
|
||||
interface.io.mstDeltaTime := slaveParser.io.mstDeltaTimeStamp
|
||||
interface.io.slvDeltaTime := slaveParser.io.slvDeltaTime
|
||||
interface.io.deltaFinal := slaveParser.io.deltaFinal
|
||||
|
||||
interface.io.intSlvTrig(0) := slaveParser.io.dSMenq(0)
|
||||
interface.io.intSlvTrig(1) := slaveParser.io.uSMdeq(0)
|
||||
interface.io.intSlvTrig(2) := slaveParser.io.dSMenq(1)
|
||||
interface.io.intSlvTrig(3) := slaveParser.io.uSMdeq(1)
|
||||
interface.io.intSlvTrig(4) := slaveParser.io.dSMenq(2)
|
||||
interface.io.intSlvTrig(5) := slaveParser.io.uSMdeq(2)
|
||||
interface.io.intSlvTrig(6) := slaveParser.io.dSMenq(3)
|
||||
interface.io.intSlvTrig(7) := slaveParser.io.uSMdeq(3)
|
||||
|
||||
interface.io.intHWTrig(0) := slaveParser.io.intHWTrig(0)
|
||||
interface.io.intHWTrig(1) := slaveParser.io.intHWTrig(1)
|
||||
|
||||
|
||||
interface.io.downRecStat := slaveParser.io.downRecStat
|
||||
interface.io.upRecStat := slaveParser.io.upRecStat
|
||||
|
||||
}
|
||||
|
||||
slaveParser.io.intHWClr(0) := interface.io.intHWTrig(0) & interface.io.intHWClr(0)
|
||||
slaveParser.io.intHWClr(1) := interface.io.intHWTrig(1) & interface.io.intHWClr(1)
|
||||
downCDRIn.reset := reset.asBool | RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) )
|
||||
upCDRIn.reset := reset.asBool | RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) )
|
||||
downCDROut.reset := reset.asBool | RegNext( interface.io.intHWTrig(0) & interface.io.intHWClr(0) )
|
||||
upCDROut.reset := reset.asBool | RegNext( interface.io.intHWTrig(1) & interface.io.intHWClr(1) )
|
||||
|
||||
interface.io.lvds <> slaveParser.io.lvds
|
||||
|
||||
interface.io.localDevIndex := slaveParser.io.localDevIndex
|
||||
|
||||
//从站链路寄存器
|
||||
// interface.io.isDevOnLeft := slaveParser.io.isDevOnLeft
|
||||
// interface.io.isDevOnLeftModify := slaveParser.io.isDevOnLeftModify
|
||||
// interface.io.indexOfLeftDev := slaveParser.io.indexOfLeftDev
|
||||
interface.io.isDevOnRight := slaveParser.io.isDevOnRight
|
||||
interface.io.isDevOnRightModify := slaveParser.io.isDevOnRightModify
|
||||
interface.io.indexOfRightDev := slaveParser.io.indexOfRightDev
|
||||
}
|
||||
|
||||
|
||||
trait ShinTopWatchDog{ this: ShinTopBase =>
|
||||
|
||||
//看门狗1~16,SM监控
|
||||
val isWdtSMEnable = for( _ <- 0 until 16 ) yield { RegInit(false.B) }
|
||||
val wdtSMCnt = for( _ <- 0 until 16 ) yield { Reg(UInt(32.W)) }
|
||||
|
||||
for( i <- 0 until 8 ){
|
||||
when( smUnit(i).io.enq ){
|
||||
isWdtSMEnable(2*i) := false.B
|
||||
} .elsewhen( ~isWdtSMEnable(2*i) & smUnit(i).io.sram_w.enw & interface.io.cReg.wdtEnable.extract(i+1) ){
|
||||
isWdtSMEnable(2*i) := true.B
|
||||
}
|
||||
|
||||
when( smUnit(i).io.deq ){
|
||||
isWdtSMEnable(2*i + 1) := false.B
|
||||
} .elsewhen( ~isWdtSMEnable(2*i + 1) & smUnit(i).io.sram_r.enr & interface.io.cReg.wdtEnable.extract(i+1) ){
|
||||
isWdtSMEnable(2*i + 1) := true.B
|
||||
}
|
||||
}
|
||||
|
||||
for( i <- 0 until 16 ){
|
||||
when( isWdtSMEnable(i) & (wdtSMCnt(i) < interface.io.cReg.wdtTarCnt(i+1)) ){
|
||||
wdtSMCnt(i) := wdtSMCnt(i) + 1.U
|
||||
} .elsewhen( ~isWdtSMEnable(i) || (wdtSMCnt(i) >= interface.io.cReg.wdtTarCnt(i+1)) ){
|
||||
wdtSMCnt(i) := 0.U
|
||||
}
|
||||
|
||||
// assert( wdtSMCnt(i) <= interface.io.cReg.wdtTarCnt(i+1), s"Assert Failed! wdtSMCnt($i) is larger than wdtTarCnt, Special situation?" )
|
||||
|
||||
interface.io.wdtTrigger(i+1) := wdtSMCnt(i) === interface.io.cReg.wdtTarCnt(i+1)
|
||||
}
|
||||
|
||||
//看门狗0 发送后回包是否超时
|
||||
val isWdtRec2RtnEnable = RegInit(false.B)
|
||||
val wdtRec2RtnCnt = Reg(UInt(32.W))
|
||||
|
||||
when(
|
||||
(upCDRIn.io.axis.fire & upCDRIn.io.axis.bits.tlast) |
|
||||
~interface.io.cReg.wdtEnable.extract(0)
|
||||
){
|
||||
isWdtRec2RtnEnable := false.B
|
||||
} .elsewhen( ~isWdtRec2RtnEnable & downCDROut.io.axis.fire & interface.io.cReg.wdtEnable.extract(0) ){
|
||||
isWdtRec2RtnEnable := true.B
|
||||
}
|
||||
|
||||
when( isWdtRec2RtnEnable & (wdtRec2RtnCnt < interface.io.cReg.wdtTarCnt(0)) ){
|
||||
wdtRec2RtnCnt := wdtRec2RtnCnt + 1.U
|
||||
} .elsewhen( ~isWdtRec2RtnEnable || (wdtRec2RtnCnt >= interface.io.cReg.wdtTarCnt(0)) ){
|
||||
wdtRec2RtnCnt := 0.U
|
||||
}
|
||||
|
||||
// assert( wdtRecCnt < interface.io.cReg.wdtTarCnt(0), "Assert Failed! wdtRecCnt is larger than wdtTarCnt, Special situation?" )
|
||||
|
||||
interface.io.wdtTrigger(0) := wdtRec2RtnCnt === interface.io.cReg.wdtTarCnt(0)
|
||||
|
||||
//看门狗17
|
||||
val wdtRec2RecCnt = Reg(UInt(32.W))
|
||||
|
||||
when( interface.io.cReg.wdtEnable.extract(17) & (wdtRec2RecCnt < interface.io.cReg.wdtTarCnt(17)) ){
|
||||
wdtRec2RecCnt := wdtRec2RecCnt + 1.U
|
||||
} .elsewhen(
|
||||
~interface.io.cReg.wdtEnable.extract(17) ||
|
||||
downCDRIn.io.axis.fire ||
|
||||
(wdtRec2RecCnt >= interface.io.cReg.wdtTarCnt(17))
|
||||
){
|
||||
wdtRec2RecCnt := 0.U
|
||||
}
|
||||
|
||||
interface.io.wdtTrigger(17) := wdtRec2RecCnt === interface.io.cReg.wdtTarCnt(17)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ShinTop extends ShinTopBase
|
||||
with ShinTopMaster
|
||||
with ShinTopSlave
|
||||
with ShinTopWatchDog{
|
||||
|
||||
when( interface.io.cReg.modeSel === false.B ){ //slave
|
||||
when( (slaveParser.io.intHWTrig(0) | slaveParser.io.intHWTrig(1)) | interface.io.isPoReset ){ //硬件错误
|
||||
downCDRIn.io.serDat := false.B
|
||||
upCDRIn.io.serDat := false.B
|
||||
when( slaveParser.io.isLoop ){ //回环
|
||||
io.dDatOut := false.B
|
||||
io.uDatOut := io.dDatIn
|
||||
} .otherwise{ //非回环
|
||||
io.dDatOut := io.dDatIn
|
||||
io.uDatOut := io.uDatIn
|
||||
}
|
||||
} .otherwise{ //无硬件错误
|
||||
when( slaveParser.io.isLoop ){ //回环
|
||||
downCDRIn.io.serDat := io.dDatIn
|
||||
upCDRIn.io.serDat := downCDROut.io.serDat
|
||||
io.dDatOut := false.B
|
||||
io.uDatOut := upCDROut.io.serDat
|
||||
} .otherwise{ //非回环
|
||||
downCDRIn.io.serDat := io.dDatIn
|
||||
upCDRIn.io.serDat := io.uDatIn
|
||||
io.dDatOut := downCDROut.io.serDat
|
||||
io.uDatOut := upCDROut.io.serDat
|
||||
}
|
||||
}
|
||||
} .otherwise{ //master
|
||||
downCDRIn.io.serDat := false.B
|
||||
upCDRIn.io.serDat := io.uDatIn
|
||||
io.dDatOut := downCDROut.io.serDat
|
||||
io.uDatOut := false.B
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ class SlaveParserIO extends Bundle{
|
||||
|
||||
val mstDeltaTimeStamp = Output(UInt(32.W))
|
||||
val slvDeltaTime = Output(UInt(32.W))
|
||||
val deltaFinal = Output(UInt(32.W))
|
||||
val deltaFinal = Output(UInt(64.W))
|
||||
|
||||
val isLoop = Output(Bool())
|
||||
|
||||
@@ -82,7 +82,7 @@ class SlaveParserIO extends Bundle{
|
||||
val upRecStat = Output(new Stat_IO_Bundle)
|
||||
}
|
||||
|
||||
abstract class SlaveParserBase extends Module{
|
||||
abstract class SlaveParserBase extends Module with RequireAsyncReset{
|
||||
val io: SlaveParserIO = IO(new SlaveParserIO)
|
||||
|
||||
val sReg = io.sReg
|
||||
@@ -812,6 +812,15 @@ trait SlaveParserRW{ this: SlaveParserBase =>
|
||||
|
||||
|
||||
trait SlaveParserSync{ this: SlaveParserBase =>
|
||||
val addr64_op1 = WireDefault( 0.U(64.W) )
|
||||
val addr64_op2 = WireDefault( 0.U(64.W) )
|
||||
def subOp2(x:UInt) = ~x + 1.U
|
||||
val addr64_res = addr64_op1 + addr64_op2
|
||||
|
||||
val addrConflict = WireDefault(VecInit(Seq.fill(4){false.B}))
|
||||
dontTouch(addrConflict)
|
||||
assert( PopCount(addrConflict) <= 1.U )
|
||||
|
||||
|
||||
//下行接收
|
||||
when( downRecParser.io.subMsgTailReq.fire ){
|
||||
@@ -837,9 +846,9 @@ trait SlaveParserSync{ this: SlaveParserBase =>
|
||||
val mstDeltaTimeStamp = Reg(UInt(32.W)); io.mstDeltaTimeStamp := mstDeltaTimeStamp //主站时间戳差值
|
||||
val slvDeltaTimeStamp = Reg(UInt(32.W)); io.slvDeltaTime := slvDeltaTimeStamp //从站时间戳差值
|
||||
|
||||
val mstSlvDeltaTimeStamp = Reg(UInt(32.W)) //主发从接时间差(中间变量)
|
||||
val deltaMstSlvDeltaTimeStamp = Reg(UInt(32.W)) //主差从差时间差(中间变量)
|
||||
val deltaFinal = Reg(UInt(32.W)); io.deltaFinal := deltaFinal //当前时间戳与主站时间差
|
||||
val mstSlvDeltaTimeStamp = Reg(UInt(64.W)) //主发从接时间差(中间变量)
|
||||
val deltaMstSlvDeltaTimeStamp = Reg(UInt(64.W)) //主差从差时间差(中间变量)
|
||||
val deltaFinal = Reg(UInt(64.W)); io.deltaFinal := deltaFinal //当前时间戳与主站时间差
|
||||
|
||||
|
||||
// val recoTimeStamp = Reg(UInt(64.W)) //时钟补偿寄存器
|
||||
@@ -860,7 +869,12 @@ trait SlaveParserSync{ this: SlaveParserBase =>
|
||||
//更新上行本地时间戳寄存器
|
||||
when( upRecParser.io.frameReq.fire & upRecParser.io.frameReq.bits.frameStyle === FRAME_STYLE_COMMON ){
|
||||
upTimeStamp := io.cReg.timeStamp
|
||||
slvDeltaTimeStamp := io.cReg.timeStamp - downTimeStamp
|
||||
|
||||
// slvDeltaTimeStamp := io.cReg.timeStamp - downTimeStamp
|
||||
addr64_op1 := io.cReg.timeStamp //组合逻辑
|
||||
addr64_op2 := subOp2(downTimeStamp) //组合逻辑
|
||||
addrConflict(0) := true.B //组合逻辑
|
||||
slvDeltaTimeStamp := addr64_res //时序逻辑
|
||||
}
|
||||
|
||||
//下行接收
|
||||
@@ -898,7 +912,13 @@ trait SlaveParserSync{ this: SlaveParserBase =>
|
||||
} .elsewhen( syncCnt === 7.U ){
|
||||
mstTimeStamp := Cat( downRecParser.io.data.bits, mstTimeStamp(55,0) )
|
||||
} .elsewhen( syncCnt === 8.U ){
|
||||
mstSlvDeltaTimeStamp := mstTimeStamp - downTimeStamp
|
||||
// mstSlvDeltaTimeStamp := mstTimeStamp - downTimeStamp
|
||||
|
||||
addr64_op1 := mstTimeStamp //组合逻辑
|
||||
addr64_op2 := subOp2(downTimeStamp) //组合逻辑
|
||||
addrConflict(1) := true.B //组合逻辑
|
||||
mstSlvDeltaTimeStamp := addr64_res //时序逻辑
|
||||
|
||||
mstDeltaTimeStamp := Cat( mstDeltaTimeStamp(31, 8), downRecParser.io.data.bits )
|
||||
} .elsewhen( syncCnt === 9.U ){
|
||||
mstDeltaTimeStamp := Cat( mstDeltaTimeStamp(31,16), downRecParser.io.data.bits, mstDeltaTimeStamp(7,0) )
|
||||
@@ -912,10 +932,19 @@ trait SlaveParserSync{ this: SlaveParserBase =>
|
||||
}
|
||||
|
||||
when( RegNext(isSync) & ~isSync ){
|
||||
val deltaMstSlvDeltaTimeStamp_org = mstDeltaTimeStamp - slvDeltaTimeStamp
|
||||
deltaMstSlvDeltaTimeStamp := Cat( deltaMstSlvDeltaTimeStamp_org.extract(deltaMstSlvDeltaTimeStamp_org.getWidth-1), deltaMstSlvDeltaTimeStamp_org(deltaMstSlvDeltaTimeStamp_org.getWidth-1, 1) ) //(mstDeltaTimeStamp - slvDeltaTimeStamp) >> 1
|
||||
// deltaMstSlvDeltaTimeStamp := (mstDeltaTimeStamp - slvDeltaTimeStamp) >>> 1 //(mstDeltaTimeStamp - slvDeltaTimeStamp) >> 1
|
||||
|
||||
addr64_op1 := Cat( Fill(32, mstDeltaTimeStamp(31)), mstDeltaTimeStamp) //组合逻辑
|
||||
addr64_op2 := subOp2( Cat( Fill(32, slvDeltaTimeStamp(31)), slvDeltaTimeStamp) ) //组合逻辑
|
||||
addrConflict(2) := true.B //组合逻辑
|
||||
deltaMstSlvDeltaTimeStamp := Cat(addr64_res(63),addr64_res(63,1)) //时序逻辑
|
||||
|
||||
} .elsewhen( RegNext(RegNext(isSync)) & ~RegNext(isSync) ){
|
||||
deltaFinal := mstSlvDeltaTimeStamp + deltaMstSlvDeltaTimeStamp
|
||||
// deltaFinal := mstSlvDeltaTimeStamp + deltaMstSlvDeltaTimeStamp
|
||||
addr64_op1 := mstSlvDeltaTimeStamp //组合逻辑
|
||||
addr64_op2 := deltaMstSlvDeltaTimeStamp //组合逻辑
|
||||
addrConflict(3) := true.B //组合逻辑
|
||||
deltaFinal := addr64_res //时序逻辑
|
||||
}
|
||||
|
||||
|
||||
@@ -991,11 +1020,11 @@ with SlaveParserProbe{
|
||||
io.intHWTrig(0) := downRecParser.io.isError
|
||||
io.intHWTrig(1) := upRecParser.io.isError
|
||||
|
||||
downRecParser.reset := reset.asBool | RegNext(downRecParser.io.isError & io.intHWClr(0))
|
||||
downSendGen.reset := reset.asBool | RegNext(downRecParser.io.isError & io.intHWClr(0))
|
||||
downRecParser.io.flush := RegNext(downRecParser.io.isError & io.intHWClr(0))
|
||||
downSendGen.io.flush := RegNext(downRecParser.io.isError & io.intHWClr(0))
|
||||
|
||||
upRecParser.reset := reset.asBool | RegNext(upRecParser.io.isError & io.intHWClr(1))
|
||||
upSendGen.reset := reset.asBool | RegNext(upRecParser.io.isError & io.intHWClr(1))
|
||||
upRecParser.io.flush := RegNext(upRecParser.io.isError & io.intHWClr(1))
|
||||
upSendGen.io.flush := RegNext(upRecParser.io.isError & io.intHWClr(1))
|
||||
|
||||
io.downRecStat := downRecParser.io.stat
|
||||
io.upRecStat := upRecParser.io.stat
|
||||
|
||||
@@ -20,10 +20,10 @@ class SlaveRecParserIO extends Bundle{
|
||||
|
||||
val stat = Output(new Stat_IO_Bundle)
|
||||
|
||||
|
||||
val flush = Input(Bool())
|
||||
}
|
||||
|
||||
class SlaveRecParser extends Module{
|
||||
class SlaveRecParser extends Module with RequireAsyncReset{
|
||||
val io: SlaveRecParserIO = IO(new SlaveRecParserIO)
|
||||
|
||||
val crc = Module(new crc32_8)
|
||||
@@ -53,7 +53,7 @@ class SlaveRecParser extends Module{
|
||||
|
||||
crc.io.dataIn := io.rec.bits.tdata
|
||||
|
||||
crc.reset := reset.asBool | stateCurr === STATE_IDLE
|
||||
crc.io.flush := stateCurr === STATE_IDLE | io.flush
|
||||
|
||||
val crcData = Reg(UInt(32.W))
|
||||
val isCrcPass = crc.io.crc === Cat( crcData(23,0), io.rec.bits.tdata )
|
||||
@@ -96,7 +96,9 @@ class SlaveRecParser extends Module{
|
||||
|
||||
io.subMsgTailReq.bits.workCnt := subMsgTail.workCnt | io.rec.bits.tdata(7,0)
|
||||
|
||||
when( io.rec.fire ){
|
||||
when( io.flush ){
|
||||
lengthCnt := 0.U
|
||||
} .elsewhen( io.rec.fire ){
|
||||
when( stateCurr =/= stateNext ){
|
||||
lengthCnt := 0.U
|
||||
} .otherwise{
|
||||
@@ -177,36 +179,38 @@ class SlaveRecParser extends Module{
|
||||
|
||||
|
||||
stateNext :=
|
||||
Mux1H(Seq(
|
||||
//必须使用上升沿触发,以避免前一帧长度超过预期
|
||||
( stateCurr === STATE_IDLE ) -> Mux( ~RegNext(io.rec.valid) & io.rec.valid, STATE_HEADER, STATE_IDLE ),
|
||||
( stateCurr === STATE_HEADER ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast, STATE_ERROR,
|
||||
Mux( lengthCnt === (4-1).U,
|
||||
MuxCase( STATE_ERROR, Array(
|
||||
( frameHeader.frameStyle === FRAME_STYLE_COMMON ) -> STATE_SUBMSG_HEADER,
|
||||
( frameHeader.frameStyle === FRAME_STYLE_PROBE ) -> STATE_CRC,
|
||||
Mux( io.flush, STATE_IDLE,
|
||||
Mux1H(Seq(
|
||||
//必须使用上升沿触发,以避免前一帧长度超过预期
|
||||
( stateCurr === STATE_IDLE ) -> Mux( ~RegNext(io.rec.valid) & io.rec.valid, STATE_HEADER, STATE_IDLE ),
|
||||
( stateCurr === STATE_HEADER ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast, STATE_ERROR,
|
||||
Mux( lengthCnt === (4-1).U,
|
||||
MuxCase( STATE_ERROR, Array(
|
||||
( frameHeader.frameStyle === FRAME_STYLE_COMMON ) -> STATE_SUBMSG_HEADER,
|
||||
( frameHeader.frameStyle === FRAME_STYLE_PROBE ) -> STATE_CRC,
|
||||
)), STATE_HEADER
|
||||
)), STATE_HEADER
|
||||
)), STATE_HEADER
|
||||
),
|
||||
( stateCurr === STATE_SUBMSG_HEADER ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast, STATE_ERROR,
|
||||
Mux( lengthCnt === (6-1).U, STATE_PAYLOAD_DATA, STATE_SUBMSG_HEADER )
|
||||
), STATE_SUBMSG_HEADER),
|
||||
|
||||
( stateCurr === STATE_PAYLOAD_DATA ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast | isDataRejErr, STATE_ERROR,
|
||||
Mux( lengthCnt === ( subMsgHeader.length - 1.U), STATE_SUBMSG_TAIL, STATE_PAYLOAD_DATA )
|
||||
), STATE_PAYLOAD_DATA),
|
||||
|
||||
( stateCurr === STATE_SUBMSG_TAIL ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast, STATE_ERROR,
|
||||
Mux( lengthCnt === ( (2 - 1).U),
|
||||
Mux( frameLenCnt === frameHeader.frameLenAim - 1.U, STATE_CRC, STATE_SUBMSG_HEADER
|
||||
),STATE_SUBMSG_TAIL )
|
||||
), STATE_SUBMSG_TAIL),
|
||||
|
||||
( stateCurr === STATE_CRC ) -> Mux( io.rec.fire & io.rec.bits.tlast,
|
||||
Mux( lengthCnt === (4 - 1).U & isCrcPass, STATE_IDLE, STATE_ERROR ), STATE_CRC
|
||||
),
|
||||
( stateCurr === STATE_SUBMSG_HEADER ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast, STATE_ERROR,
|
||||
Mux( lengthCnt === (6-1).U, STATE_PAYLOAD_DATA, STATE_SUBMSG_HEADER )
|
||||
), STATE_SUBMSG_HEADER),
|
||||
|
||||
( stateCurr === STATE_PAYLOAD_DATA ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast | isDataRejErr, STATE_ERROR,
|
||||
Mux( lengthCnt === ( subMsgHeader.length - 1.U), STATE_SUBMSG_TAIL, STATE_PAYLOAD_DATA )
|
||||
), STATE_PAYLOAD_DATA),
|
||||
|
||||
( stateCurr === STATE_SUBMSG_TAIL ) -> Mux( io.rec.fire, Mux(io.rec.bits.tlast, STATE_ERROR,
|
||||
Mux( lengthCnt === ( (2 - 1).U),
|
||||
Mux( frameLenCnt === frameHeader.frameLenAim - 1.U, STATE_CRC, STATE_SUBMSG_HEADER
|
||||
),STATE_SUBMSG_TAIL )
|
||||
), STATE_SUBMSG_TAIL),
|
||||
|
||||
( stateCurr === STATE_CRC ) -> Mux( io.rec.fire & io.rec.bits.tlast,
|
||||
Mux( lengthCnt === (4 - 1).U & isCrcPass, STATE_IDLE, STATE_ERROR ), STATE_CRC
|
||||
),
|
||||
( stateCurr === STATE_ERROR ) -> STATE_ERROR,
|
||||
))
|
||||
( stateCurr === STATE_ERROR ) -> STATE_ERROR,
|
||||
))
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,12 +22,14 @@ class SlaveSendGenIO extends Bundle{
|
||||
|
||||
val isError = Output(Bool())
|
||||
val stateCurr = Output(UInt(3.W))
|
||||
|
||||
val flush = Input(Bool())
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class SlaveSendGen extends Module{
|
||||
class SlaveSendGen extends Module with RequireAsyncReset{
|
||||
val io: SlaveSendGenIO = IO(new SlaveSendGenIO)
|
||||
|
||||
|
||||
@@ -60,7 +62,7 @@ class SlaveSendGen extends Module{
|
||||
|
||||
|
||||
|
||||
crc.reset := reset.asBool | stateCurr === STATE_IDLE
|
||||
crc.io.flush := stateCurr === STATE_IDLE | io.flush
|
||||
|
||||
|
||||
|
||||
@@ -112,30 +114,33 @@ class SlaveSendGen extends Module{
|
||||
assert( ~(io.subMsgTailReq.ready & ~io.subMsgTailReq.valid) )
|
||||
|
||||
|
||||
stateNext := Mux1H(Seq(
|
||||
(stateCurr === STATE_IDLE) -> Mux( io.frameReq.fire, STATE_FRAME_HEADER, STATE_IDLE ),
|
||||
(stateCurr === STATE_FRAME_HEADER) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, Mux(
|
||||
frameInfo.frameStyle === FRAME_STYLE_COMMON,
|
||||
Mux(io.subMsgHeadReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT),
|
||||
STATE_CRC ),
|
||||
STATE_FRAME_HEADER), STATE_FRAME_HEADER ),
|
||||
(stateCurr === STATE_SUBMSG_HEADER) -> Mux( io.send.fire, Mux( lengthCnt === (6-1).U, STATE_SUBMSG_DATA, STATE_SUBMSG_HEADER), STATE_SUBMSG_HEADER),
|
||||
|
||||
(stateCurr === STATE_SUBMSG_DATA) -> Mux( io.send.fire,
|
||||
Mux( lengthCnt === subMsgHeadInfo.length-1.U, STATE_SUBMSG_TAIL, STATE_SUBMSG_DATA ), //已经发送完成该子报文
|
||||
STATE_SUBMSG_DATA ),
|
||||
|
||||
(stateCurr === STATE_SUBMSG_TAIL) -> Mux( io.send.fire,
|
||||
Mux( lengthCnt === (2-1).U, //已经发送完成该子报文尾
|
||||
Mux( frameLenCnt === frameInfo.frameLenAim -1.U, STATE_CRC, //主报文长度达到, 进CRC
|
||||
Mux( io.subMsgHeadReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT ) ), //主报文长度未到,进下一个子报文
|
||||
STATE_SUBMSG_TAIL
|
||||
), STATE_SUBMSG_TAIL ),
|
||||
stateNext :=
|
||||
Mux( io.flush, STATE_IDLE,
|
||||
Mux1H(Seq(
|
||||
(stateCurr === STATE_IDLE) -> Mux( io.frameReq.fire, STATE_FRAME_HEADER, STATE_IDLE ),
|
||||
(stateCurr === STATE_FRAME_HEADER) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, Mux(
|
||||
frameInfo.frameStyle === FRAME_STYLE_COMMON,
|
||||
Mux(io.subMsgHeadReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT),
|
||||
STATE_CRC ),
|
||||
STATE_FRAME_HEADER), STATE_FRAME_HEADER ),
|
||||
(stateCurr === STATE_SUBMSG_HEADER) -> Mux( io.send.fire, Mux( lengthCnt === (6-1).U, STATE_SUBMSG_DATA, STATE_SUBMSG_HEADER), STATE_SUBMSG_HEADER),
|
||||
|
||||
(stateCurr === STATE_SUBMSG_DATA) -> Mux( io.send.fire,
|
||||
Mux( lengthCnt === subMsgHeadInfo.length-1.U, STATE_SUBMSG_TAIL, STATE_SUBMSG_DATA ), //已经发送完成该子报文
|
||||
STATE_SUBMSG_DATA ),
|
||||
|
||||
(stateCurr === STATE_SUBMSG_TAIL) -> Mux( io.send.fire,
|
||||
Mux( lengthCnt === (2-1).U, //已经发送完成该子报文尾
|
||||
Mux( frameLenCnt === frameInfo.frameLenAim -1.U, STATE_CRC, //主报文长度达到, 进CRC
|
||||
Mux( io.subMsgHeadReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT ) ), //主报文长度未到,进下一个子报文
|
||||
STATE_SUBMSG_TAIL
|
||||
), STATE_SUBMSG_TAIL ),
|
||||
|
||||
(stateCurr === STATE_CRC) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, STATE_IDLE, STATE_CRC ), STATE_CRC),
|
||||
// (stateCurr === STATE_ERROR) -> Mux( io.send.fire, STATE_IDLE, STATE_ERROR),
|
||||
(stateCurr === STATE_WAIT) -> Mux( io.subMsgHeadReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT),
|
||||
))
|
||||
(stateCurr === STATE_CRC) -> Mux( io.send.fire, Mux( lengthCnt === (4-1).U, STATE_IDLE, STATE_CRC ), STATE_CRC),
|
||||
// (stateCurr === STATE_ERROR) -> Mux( io.send.fire, STATE_IDLE, STATE_ERROR),
|
||||
(stateCurr === STATE_WAIT) -> Mux( io.subMsgHeadReq.valid, STATE_SUBMSG_HEADER, STATE_WAIT),
|
||||
))
|
||||
)
|
||||
|
||||
io.data(0).ready := io.send.fire & (stateCurr === STATE_SUBMSG_DATA) & (subMsgHeadInfo.source === 0.U)
|
||||
io.data(1).ready := io.send.fire & (stateCurr === STATE_SUBMSG_DATA) & (subMsgHeadInfo.source === 1.U)
|
||||
|
||||
@@ -28,7 +28,7 @@ class RegAccessInterfaceIO extends Bundle{
|
||||
val isEnR = Output(Bool())
|
||||
}
|
||||
|
||||
abstract class SpiInterfaceBase extends Module{
|
||||
abstract class SpiInterfaceBase extends Module with RequireAsyncReset{
|
||||
val io = IO(new RegAccessInterfaceIO)
|
||||
|
||||
val sck = Wire(Bool())
|
||||
|
||||
Reference in New Issue
Block a user