2025-01-09 19:10:07 +08:00
|
|
|
package BACK
|
|
|
|
|
|
|
|
|
|
import chisel3._
|
|
|
|
|
import chisel3.util._
|
|
|
|
|
|
|
|
|
|
class AXIS_Bundle(dw: Int) extends Bundle{
|
|
|
|
|
val tdata = UInt(dw.W)
|
|
|
|
|
val tlast = Bool()
|
|
|
|
|
val tuser = Bool()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//work in 100MHZ
|
|
|
|
|
class CDROutIO extends Bundle{
|
|
|
|
|
val axis = Flipped(Decoupled(new AXIS_Bundle(8)))
|
|
|
|
|
val serDat = Output(Bool())
|
|
|
|
|
|
2025-05-22 16:53:42 +08:00
|
|
|
|
|
|
|
|
}
|
2025-01-09 19:10:07 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class CDROut extends Module{
|
|
|
|
|
val io: CDROutIO = IO(new CDROutIO)
|
2025-08-11 10:05:49 +08:00
|
|
|
def PRE_NUM = 3 //PRE_NUM should >= 2
|
2025-05-22 16:53:42 +08:00
|
|
|
|
|
|
|
|
|
2025-01-09 19:10:07 +08:00
|
|
|
def STATE_IDLE = 0.U
|
|
|
|
|
def STATE_PREAMBLE = 1.U
|
|
|
|
|
def STATE_PAYLOAD = 2.U
|
|
|
|
|
|
2025-03-04 10:58:59 +08:00
|
|
|
val ETH_PRE = "b1100010001".U(10.W)
|
|
|
|
|
val ETH_SFD = "b0110100111".U(10.W)
|
2025-01-09 19:10:07 +08:00
|
|
|
|
|
|
|
|
val stateNext = Wire(UInt(2.W))
|
|
|
|
|
val stateCurr = RegNext( stateNext, 0.U )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val bitCnt = Reg(UInt(4.W))
|
|
|
|
|
val byteCnt = Reg(UInt(3.W)) //payload dont need to count
|
|
|
|
|
|
|
|
|
|
val shiftData = RegInit(0.U(10.W))
|
|
|
|
|
|
|
|
|
|
stateNext := Mux1H(Seq(
|
|
|
|
|
(stateCurr === STATE_IDLE) -> ( Mux( io.axis.valid, STATE_PREAMBLE, STATE_IDLE )),
|
2025-08-07 17:39:11 +08:00
|
|
|
(stateCurr === STATE_PREAMBLE) -> ( Mux( (byteCnt === (PRE_NUM-1).U) & (bitCnt === 9.U), Mux( io.axis.valid, STATE_PAYLOAD, STATE_IDLE), STATE_PREAMBLE )),
|
2025-07-15 16:30:44 +08:00
|
|
|
(stateCurr === STATE_PAYLOAD) -> ( Mux( (io.axis.fire & io.axis.bits.tlast) | (~io.axis.valid & io.axis.ready), STATE_IDLE, STATE_PAYLOAD ) ),
|
2025-01-09 19:10:07 +08:00
|
|
|
))
|
|
|
|
|
|
|
|
|
|
io.serDat := shiftData.extract(9)
|
|
|
|
|
io.axis.ready :=
|
|
|
|
|
bitCnt === 9.U & (
|
2025-08-07 17:39:11 +08:00
|
|
|
(stateCurr === STATE_PREAMBLE & byteCnt === (PRE_NUM-1).U) |
|
2025-01-09 19:10:07 +08:00
|
|
|
(stateCurr === STATE_PAYLOAD)
|
|
|
|
|
)
|
|
|
|
|
|
2025-05-26 11:52:40 +08:00
|
|
|
// assert( ~(~io.axis.valid & io.axis.ready) )
|
|
|
|
|
when( ~io.axis.valid & io.axis.ready ){
|
|
|
|
|
printf( "Error, CDROut axis overflow!\n" )
|
|
|
|
|
}
|
2025-05-20 11:35:11 +08:00
|
|
|
|
2025-01-09 19:10:07 +08:00
|
|
|
|
2025-07-17 10:03:31 +08:00
|
|
|
|
|
|
|
|
when( stateCurr === STATE_IDLE & stateNext === STATE_PREAMBLE){ //PRE
|
|
|
|
|
shiftData := ETH_PRE
|
2025-01-09 19:10:07 +08:00
|
|
|
} .otherwise{
|
|
|
|
|
when( bitCnt =/= 9.U ){
|
|
|
|
|
shiftData := shiftData << 1
|
|
|
|
|
} .otherwise{ //bitCnt === 9.U
|
|
|
|
|
when( stateCurr === STATE_PREAMBLE ){
|
2025-03-04 10:58:59 +08:00
|
|
|
shiftData := MuxCase( ETH_PRE, Array(
|
2025-08-07 17:39:11 +08:00
|
|
|
( byteCnt === (PRE_NUM-2).U ) -> ETH_SFD,
|
|
|
|
|
( byteCnt === (PRE_NUM-1).U ) -> Dualb4b5Encoder(io.axis.bits.tdata),
|
2025-01-09 19:10:07 +08:00
|
|
|
))
|
|
|
|
|
} .elsewhen( stateCurr === STATE_PAYLOAD ){
|
2025-07-30 15:36:18 +08:00
|
|
|
shiftData := Dualb4b5Encoder(io.axis.bits.tdata)
|
2025-01-09 19:10:07 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
when( stateCurr === STATE_IDLE ){ //PRE
|
|
|
|
|
bitCnt := 0.U
|
|
|
|
|
} .otherwise{
|
|
|
|
|
when( bitCnt === 9.U ){
|
|
|
|
|
bitCnt := 0.U
|
|
|
|
|
} .otherwise{
|
2025-02-11 15:17:02 +08:00
|
|
|
bitCnt := bitCnt + 1.U
|
2025-01-09 19:10:07 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
when( (stateCurr === STATE_IDLE) | (stateCurr === STATE_PAYLOAD) ){
|
|
|
|
|
byteCnt := 0.U
|
|
|
|
|
} .elsewhen( bitCnt === 9.U ){
|
|
|
|
|
byteCnt := byteCnt + 1.U
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|