package BACK import chisel3._ import chisel3.util._ class SimCDR extends Module with RequireAsyncReset{ val io = IO(new Bundle{ val data = Input( UInt(8.W) ) val multiCLK = Input(Vec(16, Bool())) val flush = Input(Bool()) val isSuccess = Output(Bool()) val isFailed = Output(Bool()) }) val cdrInAxis = Module(new CDRInAxis) val cdrInSample = Module(new CDRInMultiSample(clkNum = 4)) val cdrOut = Module(new CDROut) val dataCnt = RegInit(0.U(12.W)) val payloadLen = RegInit(("hFFF".U)(12.W)) val b4b5Encoder = Module(new b4b5DualEncode) val b4b5Decoder = Module(new b4b5DualDecode) val b8b10Encoder = Module(new b8b10Encode) val b8b10Decoder = Module(new b8b10Decode) val wPtr = RegInit(0.U(12.W)) val rPtr = withClockAndReset( io.multiCLK(0).asClock, reset ) { RegInit(0.U(12.W)) } val asyncFifo = Module(new ShareSRAM2k) when( cdrOut.io.axis.fire & dataCnt === 0.U ){ payloadLen := Cat( io.data, 0.U(4.W) ) } .elsewhen( cdrOut.io.axis.fire & dataCnt === 1.U ){ payloadLen := Cat( payloadLen(11,4), io.data(7,4) ) + 4.U + 4.U } when( cdrOut.io.axis.fire ){ when( dataCnt >= payloadLen - 1.U ){ dataCnt := 0.U } .otherwise{ dataCnt := dataCnt + 1.U } } cdrOut.io.flush := io.flush cdrInAxis.clock := io.multiCLK(0).asClock cdrInSample.clock := io.multiCLK(0).asClock cdrInAxis.io.flush := io.flush // cdrInSample.multiCLK := io.multiCLK cdrInSample.multiCLK(0) := io.multiCLK(0) cdrInSample.multiCLK(1) := io.multiCLK(4) cdrInSample.multiCLK(2) := io.multiCLK(8) cdrInSample.multiCLK(3) := io.multiCLK(12) cdrInAxis.io.syncSerDat := cdrInSample.io.syncSerDat cdrInSample.io.serDat := cdrOut.io.serDat val isTxEnd = cdrOut.io.axis.fire & cdrOut.io.axis.bits.tlast cdrOut.io.axis.valid := ~io.flush & ShiftRegisters( ~isTxEnd, 32 ).reduce(_&_) cdrOut.io.axis.bits.tdata := io.data cdrOut.io.axis.bits.tuser := false.B cdrOut.io.axis.bits.tlast := dataCnt === (payloadLen - 1.U) cdrInAxis.io.axis.ready := true.B io.isFailed := cdrInAxis.io.axis.fire & (asyncFifo.io.datar =/= cdrInAxis.io.axis.bits.tdata) io.isSuccess := cdrInAxis.io.axis.fire & cdrInAxis.io.axis.bits.tlast val isUsing8b10b = true.B when( isUsing8b10b ){ b8b10Encoder.io <> cdrOut.io.encode b8b10Decoder.io <> cdrInAxis.io.decode b4b5Encoder.io.isEnable := false.B b4b5Encoder.io.dataIn := 0.U b4b5Decoder.io.dataIn := 0.U } .otherwise{ b4b5Encoder.io <> cdrOut.io.encode b4b5Decoder.io <> cdrInAxis.io.decode b8b10Encoder.io.isEnable := false.B b8b10Encoder.io.dataIn := 0.U b8b10Decoder.io.dataIn := 0.U } asyncFifo.io.clockw := clock.asBool asyncFifo.io.dataw := io.data asyncFifo.io.addrw := wPtr(10,0) asyncFifo.io.enw := cdrOut.io.axis.fire asyncFifo.io.clockr := io.multiCLK(0) asyncFifo.io.addrr := rPtr(10,0) asyncFifo.io.enr := true.B when( cdrOut.io.axis.fire ){ wPtr := wPtr + 1.U } when( cdrInAxis.io.axis.fire ){ rPtr := rPtr + 1.U } val isFull = (wPtr ^ rPtr) === (1.U << log2Ceil(2048)) assert(~isFull) val coverData = RegInit(VecInit(Seq.fill(512){false.B})) when( cdrOut.io.axis.fire ){ for( i <- 0 until 256 ){ when( io.data === i.U ){ when( b8b10Encoder.rdTest ){ coverData(i) := true.B } .otherwise{ coverData(256+i) := true.B } } } } // val coverData = RegInit(VecInit(Seq.fill(256){false.B})) // when( cdrOut.io.axis.fire ){ // for( i <- 0 until 256 ){ // when( io.data === i.U ){ // coverData(i) := true.B // } // } // } val coverage = PopCount(coverData.asUInt) when( io.isSuccess ){ printf( cf"Coverage: ${coverage}\n") } }