* PRE改为K28_0 //0x1C

* SDF改为K28_3 //0x7C

* CDR_OUT CDR_IN补充状态state_ctrl
* 编码的isCtrl在idle转preamble,preamble处最后一个,state_ctrl有效
* CDR_OUT补充对外寄存器输入ctrlWord
* CDR_IN对齐直接看decoder的控制字组合
* CDR_IN的控制字由补充状态机STATE_CTRL过滤后输出
* PRE SDF的控制字在包末尾将允许重复使用
This commit is contained in:
RuigeLee
2026-07-29 16:30:31 +08:00
parent 43369d87f7
commit 3d446383e6
7 changed files with 248 additions and 218 deletions

View File

@@ -11,6 +11,8 @@
* 停用4b5b特性 * 停用4b5b特性
- 删除选择寄存器器 h4c寄存器不再有效 - 删除选择寄存器器 h4c寄存器不再有效
- 8b10b编码解码模块改为cdrout cdrin中例化
* 增加部分控制码 * 增加部分控制码
- 所有控制码都有极性 - 所有控制码都有极性
- 控制码有对应原始码 - 控制码有对应原始码
@@ -29,9 +31,15 @@
* val isK28_2 = Output(Bool()) //0x5c IS_ENABLE_K28_2 * val isK28_2 = Output(Bool()) //0x5c IS_ENABLE_K28_2
* val isK28_6 = Output(Bool()) //0xdc IS_ENABLE_K28_6 * val isK28_6 = Output(Bool()) //0xdc IS_ENABLE_K28_6
* PRE改为K28_0 //0x1C
* SDF改为K28_3 //0x7C
* CDR_OUT CDR_IN补充状态state_ctrl
* 编码的isCtrl在idle转preamblepreamble处最后一个state_ctrl有效
* CDR_OUT补充对外寄存器输入ctrlWord
* CDR_IN对齐直接看decoder的控制字组合
* CDR_IN的控制字由补充状态机STATE_CTRL过滤后输出
* PRE SDF的控制字在包末尾将允许重复使用
--------------------------------------- ---------------------------------------

View File

@@ -165,24 +165,30 @@ class CDRInMultiSample(clkNum: Int) extends Module with RequireAsyncReset{
class CDRInAxisIO extends Bundle{ class CDRInAxisIO extends Bundle{
val axis = Decoupled(new AXIS_Bundle(8)) val axis = Decoupled(new AXIS_Bundle(8))
val decode = Flipped(new Decode_Bundle)
val syncSerDat = Input(Bool()) val syncSerDat = Input(Bool())
val flush = Input(Bool()) val flush = Input(Bool())
val isK28_0 = Output(Bool()) //0x1c
val isK28_3 = Output(Bool()) //0x7c
val isK28_4 = Output(Bool()) //0x9c
val isK28_1 = Output(Bool()) //0x3c
val isK28_2 = Output(Bool()) //0x5c
val isK28_6 = Output(Bool()) //0xdc
} }
class CDRInAxis extends Module with RequireAsyncReset{ class CDRInAxis extends Module with RequireAsyncReset{
val io: CDRInAxisIO = IO(new CDRInAxisIO) val io: CDRInAxisIO = IO(new CDRInAxisIO)
io.decode.dataIn := 0.U
def HeaderByte: Int = 4
val ETH_PRE = "h68".U(8.W) def HeaderByte: Int = 4
val ETH_SFD = "h25".U(8.W)
val STATE_IDLE = 0.U val STATE_IDLE = 0.U
val STATE_HEADER = 1.U val STATE_HEADER = 1.U
val STATE_PAYLOAD = 2.U val STATE_PAYLOAD = 2.U
val STATE_CTRL = 3.U
val stateNext = Wire(UInt(2.W)) val stateNext = Wire(UInt(2.W))
val stateCurr = RegNext( stateNext, STATE_IDLE ) val stateCurr = RegNext( stateNext, STATE_IDLE )
@@ -190,6 +196,7 @@ class CDRInAxis extends Module with RequireAsyncReset{
val bitCnt = RegInit(0.U(4.W)) val bitCnt = RegInit(0.U(4.W))
val byteCnt = RegInit(0.U((12+1).W)) val byteCnt = RegInit(0.U((12+1).W))
val decoder = Module(new b8b10Decode)
val checkSFD = RegInit( 0.U(10.W) ) val checkSFD = RegInit( 0.U(10.W) )
when( io.flush ){ when( io.flush ){
@@ -198,10 +205,10 @@ class CDRInAxis extends Module with RequireAsyncReset{
checkSFD := Cat( checkSFD(8,0), io.syncSerDat ) checkSFD := Cat( checkSFD(8,0), io.syncSerDat )
} }
io.decode.dataIn := checkSFD(9,0) decoder.io.dataIn := checkSFD(9,0)
val shiftData = io.decode.dataOut val shiftData = decoder.io.dataOut
val shiftData10Next = ShiftRegister( shiftData, 10, 0.U(8.W), true.B ) val shiftData10NextIsK28_0 = ShiftRegister( decoder.io.isK28_6, 10, false.B, true.B )
val isPreAndSfd = ( shiftData10NextIsK28_0 && decoder.io.isK28_3 )
val payloadLen = RegInit(0.U(12.W)) val payloadLen = RegInit(0.U(12.W))
when( io.flush ){ when( io.flush ){
@@ -215,17 +222,19 @@ class CDRInAxis extends Module with RequireAsyncReset{
stateNext := stateNext :=
Mux( io.flush, STATE_IDLE, Mux( io.flush, STATE_IDLE,
Mux1H(Seq( Mux1H(Seq(
(stateCurr === STATE_IDLE) -> ( Mux( shiftData10Next === ETH_PRE && shiftData === ETH_SFD , STATE_HEADER, STATE_IDLE )), //IDLE (stateCurr === STATE_IDLE) -> ( Mux( isPreAndSfd , STATE_HEADER, STATE_IDLE )), //IDLE
(stateCurr === STATE_HEADER) -> ( Mux( (byteCnt === (HeaderByte-1).U) & (bitCnt === 9.U), STATE_PAYLOAD, STATE_HEADER ) ), (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 (stateCurr === STATE_PAYLOAD) -> ( Mux( (byteCnt === (payloadLen + (4 - 1).U) ) & (bitCnt === 9.U), STATE_CTRL, STATE_PAYLOAD )), // PAYLOAD +CRC
)) //crc (stateCurr === STATE_CTRL) -> STATE_IDLE
))
) )
when( stateCurr === STATE_IDLE & ( shiftData10Next === ETH_PRE && shiftData === ETH_SFD ) ){ //first align when( stateCurr === STATE_IDLE & isPreAndSfd ){ //first align
bitCnt := 0.U bitCnt := 0.U
} .otherwise{ } .otherwise{
when( bitCnt === 9.U ){ when( bitCnt === 9.U ){
@@ -237,7 +246,7 @@ class CDRInAxis extends Module with RequireAsyncReset{
when( io.flush ){ when( io.flush ){
byteCnt := 0.U byteCnt := 0.U
} .elsewhen( stateCurr === STATE_IDLE & ( shiftData10Next === ETH_PRE && shiftData === ETH_SFD ) ){ //first align } .elsewhen( stateCurr === STATE_IDLE & isPreAndSfd ){ //first align
byteCnt := 0.U byteCnt := 0.U
} .elsewhen( bitCnt === 9.U ){ } .elsewhen( bitCnt === 9.U ){
when( stateCurr === STATE_HEADER ){ when( stateCurr === STATE_HEADER ){
@@ -279,6 +288,15 @@ class CDRInAxis extends Module with RequireAsyncReset{
axis_tlast := (stateCurr === STATE_PAYLOAD & stateNext === STATE_IDLE) axis_tlast := (stateCurr === STATE_PAYLOAD & stateNext === STATE_IDLE)
} }
io.isK28_0 := decoder.io.isK28_0 & (stateCurr === STATE_CTRL) //0x1c
io.isK28_3 := decoder.io.isK28_3 & (stateCurr === STATE_CTRL) //0x7c
io.isK28_4 := decoder.io.isK28_4 & (stateCurr === STATE_CTRL) //0x9c
io.isK28_1 := decoder.io.isK28_1 & (stateCurr === STATE_CTRL) //0x3c
io.isK28_2 := decoder.io.isK28_2 & (stateCurr === STATE_CTRL) //0x5c
io.isK28_6 := decoder.io.isK28_6 & (stateCurr === STATE_CTRL) //0xdc
} }
@@ -381,4 +399,5 @@ class CDRInOriSample extends Module with RequireAsyncReset{
io.syncSerDat := asyncSerDat io.syncSerDat := asyncSerDat
} }

View File

@@ -15,9 +15,8 @@ class AXIS_Bundle(dw: Int) extends Bundle{
//work in 100MHZ //work in 100MHZ
class CDROutIO extends Bundle{ class CDROutIO extends Bundle{
val axis = Flipped(Decoupled(new AXIS_Bundle(8))) val axis = Flipped(Decoupled(new AXIS_Bundle(8)))
val encode = Flipped(new Encode_Bundle)
val serDat = Output(Bool()) val serDat = Output(Bool())
val ctrlWord = Input(UInt(8.W))
val flush = Input(Bool()) val flush = Input(Bool())
@@ -34,9 +33,10 @@ class CDROut extends Module with RequireAsyncReset{
def STATE_IDLE = 0.U def STATE_IDLE = 0.U
def STATE_PREAMBLE = 1.U def STATE_PREAMBLE = 1.U
def STATE_PAYLOAD = 2.U def STATE_PAYLOAD = 2.U
def STATE_CTRL = 3.U
val ETH_PRE = "h68".U(8.W) val ETH_PRE = "h1c".U(8.W) //K28_0
val ETH_SFD = "h25".U(8.W) val ETH_SFD = "h7c".U(8.W) //K28_3
val stateNext = Wire(UInt(2.W)) val stateNext = Wire(UInt(2.W))
val stateCurr = RegNext( stateNext, 0.U ) val stateCurr = RegNext( stateNext, 0.U )
@@ -45,16 +45,21 @@ class CDROut extends Module with RequireAsyncReset{
val bitCnt = RegInit(0.U(4.W)) val bitCnt = RegInit(0.U(4.W))
val byteCnt = RegInit(0.U(3.W)) //payload dont need to count val byteCnt = RegInit(0.U(3.W)) //payload dont need to count
val encoder = Module(new b8b10Encode)
val shiftData = RegInit(0.U(10.W)) val shiftData = RegInit(0.U(10.W))
io.encode.isEnable := false.B //组合逻辑 encoder.io.isEnable := false.B //组合逻辑
io.encode.dataIn := 0.U //组合逻辑 encoder.io.isCtrl := false.B //组合逻辑
encoder.io.dataIn := 0.U //组合逻辑
stateNext := stateNext :=
Mux( io.flush, STATE_IDLE, Mux( io.flush, STATE_IDLE,
Mux1H(Seq( Mux1H(Seq(
(stateCurr === STATE_IDLE) -> ( Mux( io.axis.valid, STATE_PREAMBLE, STATE_IDLE )), (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_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 ) ), (stateCurr === STATE_PAYLOAD) -> ( Mux( (io.axis.fire & io.axis.bits.tlast) | (~io.axis.valid & io.axis.ready), STATE_CTRL, STATE_PAYLOAD ) ),
(stateCurr === STATE_CTRL) -> STATE_IDLE,
)) ))
) )
io.serDat := shiftData.extract(9) io.serDat := shiftData.extract(9)
@@ -73,24 +78,32 @@ class CDROut extends Module with RequireAsyncReset{
when( io.flush ){ when( io.flush ){
shiftData := 0.U shiftData := 0.U
} .elsewhen( stateCurr === STATE_IDLE & stateNext === STATE_PREAMBLE){ //PRE } .elsewhen( stateCurr === STATE_IDLE & stateNext === STATE_PREAMBLE){ //PRE
shiftData := io.encode.dataOut shiftData := encoder.io.dataOut
io.encode.dataIn := ETH_PRE //组合逻辑 encoder.io.isEnable := true.B //组合逻辑
io.encode.isEnable := true.B //组合逻辑 encoder.io.isCtrl := true.B
encoder.io.dataIn := ETH_PRE //组合逻辑
} .otherwise{ } .otherwise{
when( bitCnt =/= 9.U ){ when( bitCnt =/= 9.U ){
shiftData := shiftData << 1 shiftData := shiftData << 1
} .otherwise{ //bitCnt === 9.U } .otherwise{ //bitCnt === 9.U
when( stateCurr === STATE_PREAMBLE ){ when( stateCurr === STATE_PREAMBLE ){
shiftData := io.encode.dataOut shiftData := encoder.io.dataOut
io.encode.dataIn := MuxCase( ETH_PRE, Array( encoder.io.isEnable := true.B
encoder.io.isCtrl := byteCnt =/= (PRE_NUM-1).U //组合逻辑
encoder.io.dataIn := MuxCase( ETH_PRE, Array(
( byteCnt === (PRE_NUM-2).U ) -> ETH_SFD, ( byteCnt === (PRE_NUM-2).U ) -> ETH_SFD,
( byteCnt === (PRE_NUM-1).U ) -> io.axis.bits.tdata, ( byteCnt === (PRE_NUM-1).U ) -> io.axis.bits.tdata,
)) //组合逻辑 )) //组合逻辑
io.encode.isEnable := true.B //组合逻辑
} .elsewhen( stateCurr === STATE_PAYLOAD ){ } .elsewhen( stateCurr === STATE_PAYLOAD ){
io.encode.dataIn := io.axis.bits.tdata //组合逻辑 shiftData := encoder.io.dataOut
shiftData := io.encode.dataOut encoder.io.isEnable := true.B //组合逻辑
io.encode.isEnable := true.B //组合逻辑 encoder.io.isCtrl := false.B //组合逻辑
encoder.io.dataIn := io.axis.bits.tdata //组合逻辑
} .elsewhen( stateCurr === STATE_CTRL ){
shiftData := encoder.io.dataOut
encoder.io.isEnable := true.B //组合逻辑
encoder.io.isCtrl := true.B //组合逻辑
encoder.io.dataIn := io.ctrlWord //组合逻辑
} }
} }
} }

View File

@@ -54,11 +54,6 @@ abstract class MstSlvSwitchBase extends Module with RequireAsyncReset{
val slaveParser = Module(new SlaveParser ) val slaveParser = Module(new SlaveParser )
val masterParser = Module(new MasterParser) val masterParser = Module(new MasterParser)
val b8b10DownEncoder = Module(new b8b10Encode)
val b8b10DownDecoder = Module(new b8b10Decode)
val b8b10UpEncoder = Module(new b8b10Encode)
val b8b10UpDecoder = Module(new b8b10Decode)
val interface = Module(new Interface) val interface = Module(new Interface)
val downInSerDat = Wire(Bool()) val downInSerDat = Wire(Bool())
@@ -206,12 +201,6 @@ abstract class MstSlvSwitchBase extends Module with RequireAsyncReset{
} }
} }
b8b10DownEncoder.io <> downCDROut.io.encode
b8b10DownDecoder.io <> downCDRInAxis.io.decode
b8b10UpEncoder.io <> upCDROut.io.encode
b8b10UpDecoder.io <> upCDRInAxis.io.decode
//default //default
{ {
smUnit(0).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO) smUnit(0).io.sram_w := 0.U.asTypeOf(new SRAM2kWRIO)

View File

@@ -15,10 +15,11 @@ class Decode_Bundle extends Bundle{
val dataOut = Output(UInt(8.W)) val dataOut = Output(UInt(8.W))
val isK28_0 = Output(Bool()) //0x1c val isK28_0 = Output(Bool()) //0x1c
val isK28_1 = Output(Bool()) //0x3c
val isK28_2 = Output(Bool()) //0x5c
val isK28_3 = Output(Bool()) //0x7c val isK28_3 = Output(Bool()) //0x7c
val isK28_4 = Output(Bool()) //0x9c val isK28_4 = Output(Bool()) //0x9c
val isK28_1 = Output(Bool()) //0x3c
val isK28_2 = Output(Bool()) //0x5c
val isK28_6 = Output(Bool()) //0xdc val isK28_6 = Output(Bool()) //0xdc
} }

View File

@@ -16,8 +16,8 @@ object testShinModule extends App {
ChiselGeneratorAnnotation(() => { new ShinTop }), ChiselGeneratorAnnotation(() => { new ShinTop }),
)) ))
(new chisel3.stage.ChiselStage).execute( Array("--target-dir", "generated/SimCDR/", "-e", "verilog" ) ++ args, Seq( // (new chisel3.stage.ChiselStage).execute( Array("--target-dir", "generated/SimCDR/", "-e", "verilog" ) ++ args, Seq(
ChiselGeneratorAnnotation(() => { new SimCDR }), // ChiselGeneratorAnnotation(() => { new SimCDR }),
)) // ))
} }