优化信号线命名negedge_sck

This commit is contained in:
Ruige Lee (WSL)
2025-10-01 08:41:43 +08:00
parent 8f564c0146
commit 21bc57e9a7
49 changed files with 21791 additions and 21789 deletions

View File

@@ -1,384 +1,384 @@
package BACK
import chisel3._
import chisel3.util._
class CDRInSampleIO extends Bundle{
val serDat = Input(Bool())
val syncSerDat = Output(Bool())
}
class CDRInMultiSample(clkNum: Int) extends Module with RequireAsyncReset{
require( clkNum == 16 || clkNum == 4 )
val io: CDRInSampleIO = IO(new CDRInSampleIO)
//multiCLK 需要按照滞后相位接线即0为最先到达1次先
val multiCLK = IO(Input(Vec(clkNum, Bool())))
val sampleReg = Wire(Vec(clkNum, Bool()))
dontTouch(sampleReg)
for( i <- 0 until clkNum ) {
sampleReg(i) := withClockAndReset(multiCLK(i).asClock, reset.asAsyncReset){ ShiftRegister( io.serDat, 2, false.B, true.B ) }
}
val sampleReg_sync = for( i <- 0 until clkNum ) yield {
ShiftRegisters(sampleReg(i), 8, false.B, true.B)
}
for( i <- 0 until clkNum; j <- 0 until 8 ){dontTouch(sampleReg_sync(i)(j))}
val sampleReg_Align = Wire(Vec(8*clkNum,Bool()))
dontTouch(sampleReg_Align)
( 0 until 8 ).map{ gp =>
for( i <- gp*clkNum until (gp+1)*clkNum ){
sampleReg_Align(i) := sampleReg_sync(i - gp*clkNum)(8-1-gp)
}
}
val flitReg =
for( i <- 1 until (8*clkNum)-1 ) yield {
(sampleReg_Align(i-1) & sampleReg_Align(i+0)) |
(sampleReg_Align(i-1) & sampleReg_Align(i+1)) |
(sampleReg_Align(i+0) & sampleReg_Align(i+1))
}
for( i <- 0 until (8*clkNum)-2 ) {dontTouch(flitReg(i))}
val clearCnt = RegInit(0.U(4.W))
val checkCnt = RegInit(0.U(4.W))
val arbCali = RegInit(0.U( (log2Ceil(8*clkNum)).W ))
val isLock = RegInit(false.B)
when( (7*clkNum until 8*clkNum).map{ i => sampleReg_Align(i)}.reduce(_|_) === false.B ){
when( clearCnt =/= 10.U ){
clearCnt := clearCnt + 1.U
}
} .otherwise{
clearCnt := 0.U
}
when( ~isLock ){
checkCnt := 0.U
} .otherwise{
checkCnt := checkCnt + 1.U
}
//优先级电路,优先选择跳变的后一相进行操作,电路上需要做成可调的
val checkWindow = Wire( Vec(6, Bool()) )
dontTouch(checkWindow)
val lastPhase = 8*clkNum -2 - clkNum/2
checkWindow(0) :=
Mux1H( (0 until lastPhase-2).map{ i =>
(arbCali === (i+2).U) -> flitReg(i)
})
checkWindow(1) :=
Mux1H( (1 until lastPhase-1).map{ i =>
(arbCali === (i+1).U) -> flitReg(i)
})
checkWindow(2) :=
Mux1H( (2 until lastPhase).map{ i =>
(arbCali === i.U) -> flitReg(i)
})
checkWindow(3) :=
Mux1H( (3 until lastPhase+1).map{ i =>
(arbCali === (i-1).U) -> flitReg(i)
})
checkWindow(4) :=
Mux1H( (4 until lastPhase+2).map{ i =>
(arbCali === (i-2).U) -> flitReg(i)
})
checkWindow(5) := (
if( clkNum == 16 ){
Mux1H( (5 until lastPhase+3).map{ i =>
(arbCali === (i-3).U) -> flitReg(i)
})
} else{
false.B
}
)
when( ~isLock ){
for( i <- 0 until clkNum ){
val j = ((8/2)*clkNum-clkNum/2)+clkNum - i - 1
when( flitReg(j) ^ flitReg(j+1) ){
arbCali := j.U
}
}
}.elsewhen( checkCnt.andR ){ //锁定之后只允许每16cycle移动一相位
assert( arbCali >= 2.U && arbCali < lastPhase.U )
when(
(if( clkNum == 16 ) { (checkWindow(0) ^ checkWindow(1)) } else {false.B}) |
(checkWindow(1) ^ checkWindow(2))
){
when( arbCali =/= 2.U ){
arbCali := arbCali - 1.U
}
} .elsewhen(
(checkWindow(3) ^ checkWindow(4)) |
(if( clkNum == 16 ) { (checkWindow(4) ^ checkWindow(5)) } else {false.B})
){
when( arbCali =/= (lastPhase-1).U ){
arbCali := arbCali + 1.U
}
}
}
when( ~isLock ){
for( i <- 0 until clkNum ){
val j = ((8/2)*clkNum-clkNum/2)+clkNum - i - 1
when( flitReg(j) ^ flitReg(j+1) ){
isLock := true.B
}
}
} .elsewhen( clearCnt === 10.U ){
isLock := false.B
}
val asyncSerDat =
Mux1H(
(for { i <- 2 until lastPhase } yield {
(arbCali === i.U) -> flitReg(i+(clkNum/2))
})
)
io.syncSerDat := asyncSerDat
}
class CDRInAxisIO extends Bundle{
val axis = Decoupled(new AXIS_Bundle(8))
val decode = Flipped(new Decode_Bundle)
val syncSerDat = Input(Bool())
val flush = Input(Bool())
}
class CDRInAxis extends Module with RequireAsyncReset{
val io: CDRInAxisIO = IO(new CDRInAxisIO)
io.decode.dataIn := 0.U
def HeaderByte: Int = 4
val ETH_PRE = "h68".U(8.W)
val ETH_SFD = "h25".U(8.W)
val STATE_IDLE = 0.U
val STATE_HEADER = 1.U
val STATE_PAYLOAD = 2.U
val stateNext = Wire(UInt(2.W))
val stateCurr = RegNext( stateNext, STATE_IDLE )
val bitCnt = RegInit(0.U(4.W))
val byteCnt = RegInit(0.U((12+1).W))
val checkSFD = RegInit( 0.U(10.W) )
when( io.flush ){
checkSFD := 0.U
} .otherwise{
checkSFD := Cat( checkSFD(8,0), io.syncSerDat )
}
io.decode.dataIn := checkSFD(9,0)
val shiftData = io.decode.dataOut
val shiftData10Next = ShiftRegister( shiftData, 10, 0.U(8.W), true.B )
val payloadLen = RegInit(0.U(12.W))
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 :=
Mux( io.flush, STATE_IDLE,
Mux1H(Seq(
(stateCurr === STATE_IDLE) -> ( Mux( shiftData10Next === ETH_PRE && shiftData === 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
)
when( stateCurr === STATE_IDLE & ( shiftData10Next === ETH_PRE && shiftData === ETH_SFD ) ){ //first align
bitCnt := 0.U
} .otherwise{
when( bitCnt === 9.U ){
bitCnt := 0.U
} .otherwise{
bitCnt := bitCnt + 1.U
}
}
when( io.flush ){
byteCnt := 0.U
} .elsewhen( stateCurr === STATE_IDLE & ( shiftData10Next === ETH_PRE && shiftData === ETH_SFD ) ){ //first align
byteCnt := 0.U
} .elsewhen( bitCnt === 9.U ){
when( stateCurr === STATE_HEADER ){
byteCnt := Mux( byteCnt =/= (HeaderByte-1).U, byteCnt + 1.U, 0.U )
assert( byteCnt <= (HeaderByte-1).U )
} .elsewhen( stateCurr === STATE_PAYLOAD ){
byteCnt := Mux( byteCnt =/= (payloadLen+ (4-1).U), byteCnt + 1.U, 0.U )
assert( byteCnt <= ( payloadLen+ (4-1).U ) )
}
}
val axis_valid = RegInit(false.B)
val axis_tdata = RegEnable( shiftData, 0.U(8.W), bitCnt === 9.U & ( stateCurr === STATE_HEADER | stateCurr === STATE_PAYLOAD ) )
val axis_tuser = 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.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 CDRInOriSample extends Module with RequireAsyncReset{
val io: CDRInSampleIO = IO(new CDRInSampleIO)
val clkNum: Int = 16
require( clkNum == 16 )
//multiCLK 需要按照滞后相位接线即0为最先到达1次先
val multiCLK = IO(Input(Vec(clkNum, Bool())))
val sampleReg = Wire(Vec(clkNum, Bool()))
for( i <- 0 until clkNum ) {
sampleReg(i) := withClockAndReset(multiCLK(i).asClock, reset.asAsyncReset){ ShiftRegister( io.serDat, 2, false.B, true.B ) }
}
val sampleReg_sync = Wire(Vec(2*clkNum,Bool()))
for( i <- 0 until clkNum ){
sampleReg_sync(i) := ShiftRegister(sampleReg(i), 2, false.B, true.B)
}
for( i <- clkNum until 2*clkNum ){
sampleReg_sync(i) := ShiftRegister(sampleReg(i-clkNum), 1, false.B, true.B)
}
val flitReg =
for( i <- 1 until (2*clkNum)-1 ) yield {
(sampleReg_sync(i-1) & sampleReg_sync(i+0)) |
(sampleReg_sync(i-1) & sampleReg_sync(i+1)) |
(sampleReg_sync(i+0) & sampleReg_sync(i+1))
}
val clearCnt = RegInit(0.U(4.W))
val checkCnt = RegInit(0.U(4.W))
val arbLock = RegInit(0.U( (log2Ceil(2*clkNum)).W ))
val arbCali = RegInit(0.U( (log2Ceil(2*clkNum)).W ))
val isLock = RegInit(false.B)
when( sampleReg_sync.reduce(_|_) === false.B ){
when( clearCnt =/= 10.U ){
clearCnt := clearCnt + 1.U
}
} .otherwise{
clearCnt := 0.U
}
when( ~isLock ){
checkCnt := 0.U
} .otherwise{
checkCnt := checkCnt + 1.U
}
//优先级电路,优先选择跳变的后一相进行操作,电路上需要做成可调的
when( ~isLock ){
for( i <- 3 until 19 ){
val j = 19 - i - 1
when( flitReg(j) ^ flitReg(j+1) ){
arbLock := j.U
arbCali := j.U
}
}
}.elsewhen( checkCnt.andR ){ //锁定之后只允许每16cycle移动一相位
for( i <- 0 until 22 ){
val j = 22 - i -1
when( flitReg(j) ^ flitReg(j+1) ){
when( (j.U < arbCali) && ((j+3).U >= arbLock) ){
arbCali := arbCali - 1.U
} .elsewhen( (j.U > arbCali) && (j.U <= arbLock + 3.U) ){
arbCali := arbCali + 1.U
}
}
}
}
when( ~isLock ){
for( i <- 3 until 19 ){
val j = 19 - i - 1
when( flitReg(j) ^ flitReg(j+1) ){
isLock := true.B
}
}
} .elsewhen( clearCnt === 10.U ){
isLock := false.B
}
val asyncSerDat =
Mux1H(
(for { i <- 0 until 22 } yield {
(arbCali === i.U) -> flitReg(i+(8))
})
)
io.syncSerDat := asyncSerDat
}
package BACK
import chisel3._
import chisel3.util._
class CDRInSampleIO extends Bundle{
val serDat = Input(Bool())
val syncSerDat = Output(Bool())
}
class CDRInMultiSample(clkNum: Int) extends Module with RequireAsyncReset{
require( clkNum == 16 || clkNum == 4 )
val io: CDRInSampleIO = IO(new CDRInSampleIO)
//multiCLK 需要按照滞后相位接线即0为最先到达1次先
val multiCLK = IO(Input(Vec(clkNum, Bool())))
val sampleReg = Wire(Vec(clkNum, Bool()))
dontTouch(sampleReg)
for( i <- 0 until clkNum ) {
sampleReg(i) := withClockAndReset(multiCLK(i).asClock, reset.asAsyncReset){ ShiftRegister( io.serDat, 2, false.B, true.B ) }
}
val sampleReg_sync = for( i <- 0 until clkNum ) yield {
ShiftRegisters(sampleReg(i), 8, false.B, true.B)
}
for( i <- 0 until clkNum; j <- 0 until 8 ){dontTouch(sampleReg_sync(i)(j))}
val sampleReg_Align = Wire(Vec(8*clkNum,Bool()))
dontTouch(sampleReg_Align)
( 0 until 8 ).map{ gp =>
for( i <- gp*clkNum until (gp+1)*clkNum ){
sampleReg_Align(i) := sampleReg_sync(i - gp*clkNum)(8-1-gp)
}
}
val flitReg =
for( i <- 1 until (8*clkNum)-1 ) yield {
(sampleReg_Align(i-1) & sampleReg_Align(i+0)) |
(sampleReg_Align(i-1) & sampleReg_Align(i+1)) |
(sampleReg_Align(i+0) & sampleReg_Align(i+1))
}
for( i <- 0 until (8*clkNum)-2 ) {dontTouch(flitReg(i))}
val clearCnt = RegInit(0.U(4.W))
val checkCnt = RegInit(0.U(4.W))
val arbCali = RegInit(0.U( (log2Ceil(8*clkNum)).W ))
val isLock = RegInit(false.B)
when( (7*clkNum until 8*clkNum).map{ i => sampleReg_Align(i)}.reduce(_|_) === false.B ){
when( clearCnt =/= 10.U ){
clearCnt := clearCnt + 1.U
}
} .otherwise{
clearCnt := 0.U
}
when( ~isLock ){
checkCnt := 0.U
} .otherwise{
checkCnt := checkCnt + 1.U
}
//优先级电路,优先选择跳变的后一相进行操作,电路上需要做成可调的
val checkWindow = Wire( Vec(6, Bool()) )
dontTouch(checkWindow)
val lastPhase = 8*clkNum -2 - clkNum/2
checkWindow(0) :=
Mux1H( (0 until lastPhase-2).map{ i =>
(arbCali === (i+2).U) -> flitReg(i)
})
checkWindow(1) :=
Mux1H( (1 until lastPhase-1).map{ i =>
(arbCali === (i+1).U) -> flitReg(i)
})
checkWindow(2) :=
Mux1H( (2 until lastPhase).map{ i =>
(arbCali === i.U) -> flitReg(i)
})
checkWindow(3) :=
Mux1H( (3 until lastPhase+1).map{ i =>
(arbCali === (i-1).U) -> flitReg(i)
})
checkWindow(4) :=
Mux1H( (4 until lastPhase+2).map{ i =>
(arbCali === (i-2).U) -> flitReg(i)
})
checkWindow(5) := (
if( clkNum == 16 ){
Mux1H( (5 until lastPhase+3).map{ i =>
(arbCali === (i-3).U) -> flitReg(i)
})
} else{
false.B
}
)
when( ~isLock ){
for( i <- 0 until clkNum ){
val j = ((8/2)*clkNum-clkNum/2)+clkNum - i - 1
when( flitReg(j) ^ flitReg(j+1) ){
arbCali := j.U
}
}
}.elsewhen( checkCnt.andR ){ //锁定之后只允许每16cycle移动一相位
assert( arbCali >= 2.U && arbCali < lastPhase.U )
when(
(if( clkNum == 16 ) { (checkWindow(0) ^ checkWindow(1)) } else {false.B}) |
(checkWindow(1) ^ checkWindow(2))
){
when( arbCali =/= 2.U ){
arbCali := arbCali - 1.U
}
} .elsewhen(
(checkWindow(3) ^ checkWindow(4)) |
(if( clkNum == 16 ) { (checkWindow(4) ^ checkWindow(5)) } else {false.B})
){
when( arbCali =/= (lastPhase-1).U ){
arbCali := arbCali + 1.U
}
}
}
when( ~isLock ){
for( i <- 0 until clkNum ){
val j = ((8/2)*clkNum-clkNum/2)+clkNum - i - 1
when( flitReg(j) ^ flitReg(j+1) ){
isLock := true.B
}
}
} .elsewhen( clearCnt === 10.U ){
isLock := false.B
}
val asyncSerDat =
Mux1H(
(for { i <- 2 until lastPhase } yield {
(arbCali === i.U) -> flitReg(i+(clkNum/2))
})
)
io.syncSerDat := asyncSerDat
}
class CDRInAxisIO extends Bundle{
val axis = Decoupled(new AXIS_Bundle(8))
val decode = Flipped(new Decode_Bundle)
val syncSerDat = Input(Bool())
val flush = Input(Bool())
}
class CDRInAxis extends Module with RequireAsyncReset{
val io: CDRInAxisIO = IO(new CDRInAxisIO)
io.decode.dataIn := 0.U
def HeaderByte: Int = 4
val ETH_PRE = "h68".U(8.W)
val ETH_SFD = "h25".U(8.W)
val STATE_IDLE = 0.U
val STATE_HEADER = 1.U
val STATE_PAYLOAD = 2.U
val stateNext = Wire(UInt(2.W))
val stateCurr = RegNext( stateNext, STATE_IDLE )
val bitCnt = RegInit(0.U(4.W))
val byteCnt = RegInit(0.U((12+1).W))
val checkSFD = RegInit( 0.U(10.W) )
when( io.flush ){
checkSFD := 0.U
} .otherwise{
checkSFD := Cat( checkSFD(8,0), io.syncSerDat )
}
io.decode.dataIn := checkSFD(9,0)
val shiftData = io.decode.dataOut
val shiftData10Next = ShiftRegister( shiftData, 10, 0.U(8.W), true.B )
val payloadLen = RegInit(0.U(12.W))
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 :=
Mux( io.flush, STATE_IDLE,
Mux1H(Seq(
(stateCurr === STATE_IDLE) -> ( Mux( shiftData10Next === ETH_PRE && shiftData === 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
)
when( stateCurr === STATE_IDLE & ( shiftData10Next === ETH_PRE && shiftData === ETH_SFD ) ){ //first align
bitCnt := 0.U
} .otherwise{
when( bitCnt === 9.U ){
bitCnt := 0.U
} .otherwise{
bitCnt := bitCnt + 1.U
}
}
when( io.flush ){
byteCnt := 0.U
} .elsewhen( stateCurr === STATE_IDLE & ( shiftData10Next === ETH_PRE && shiftData === ETH_SFD ) ){ //first align
byteCnt := 0.U
} .elsewhen( bitCnt === 9.U ){
when( stateCurr === STATE_HEADER ){
byteCnt := Mux( byteCnt =/= (HeaderByte-1).U, byteCnt + 1.U, 0.U )
assert( byteCnt <= (HeaderByte-1).U )
} .elsewhen( stateCurr === STATE_PAYLOAD ){
byteCnt := Mux( byteCnt =/= (payloadLen+ (4-1).U), byteCnt + 1.U, 0.U )
assert( byteCnt <= ( payloadLen+ (4-1).U ) )
}
}
val axis_valid = RegInit(false.B)
val axis_tdata = RegEnable( shiftData, 0.U(8.W), bitCnt === 9.U & ( stateCurr === STATE_HEADER | stateCurr === STATE_PAYLOAD ) )
val axis_tuser = 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.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 CDRInOriSample extends Module with RequireAsyncReset{
val io: CDRInSampleIO = IO(new CDRInSampleIO)
val clkNum: Int = 16
require( clkNum == 16 )
//multiCLK 需要按照滞后相位接线即0为最先到达1次先
val multiCLK = IO(Input(Vec(clkNum, Bool())))
val sampleReg = Wire(Vec(clkNum, Bool()))
for( i <- 0 until clkNum ) {
sampleReg(i) := withClockAndReset(multiCLK(i).asClock, reset.asAsyncReset){ ShiftRegister( io.serDat, 2, false.B, true.B ) }
}
val sampleReg_sync = Wire(Vec(2*clkNum,Bool()))
for( i <- 0 until clkNum ){
sampleReg_sync(i) := ShiftRegister(sampleReg(i), 2, false.B, true.B)
}
for( i <- clkNum until 2*clkNum ){
sampleReg_sync(i) := ShiftRegister(sampleReg(i-clkNum), 1, false.B, true.B)
}
val flitReg =
for( i <- 1 until (2*clkNum)-1 ) yield {
(sampleReg_sync(i-1) & sampleReg_sync(i+0)) |
(sampleReg_sync(i-1) & sampleReg_sync(i+1)) |
(sampleReg_sync(i+0) & sampleReg_sync(i+1))
}
val clearCnt = RegInit(0.U(4.W))
val checkCnt = RegInit(0.U(4.W))
val arbLock = RegInit(0.U( (log2Ceil(2*clkNum)).W ))
val arbCali = RegInit(0.U( (log2Ceil(2*clkNum)).W ))
val isLock = RegInit(false.B)
when( sampleReg_sync.reduce(_|_) === false.B ){
when( clearCnt =/= 10.U ){
clearCnt := clearCnt + 1.U
}
} .otherwise{
clearCnt := 0.U
}
when( ~isLock ){
checkCnt := 0.U
} .otherwise{
checkCnt := checkCnt + 1.U
}
//优先级电路,优先选择跳变的后一相进行操作,电路上需要做成可调的
when( ~isLock ){
for( i <- 3 until 19 ){
val j = 19 - i - 1
when( flitReg(j) ^ flitReg(j+1) ){
arbLock := j.U
arbCali := j.U
}
}
}.elsewhen( checkCnt.andR ){ //锁定之后只允许每16cycle移动一相位
for( i <- 0 until 22 ){
val j = 22 - i -1
when( flitReg(j) ^ flitReg(j+1) ){
when( (j.U < arbCali) && ((j+3).U >= arbLock) ){
arbCali := arbCali - 1.U
} .elsewhen( (j.U > arbCali) && (j.U <= arbLock + 3.U) ){
arbCali := arbCali + 1.U
}
}
}
}
when( ~isLock ){
for( i <- 3 until 19 ){
val j = 19 - i - 1
when( flitReg(j) ^ flitReg(j+1) ){
isLock := true.B
}
}
} .elsewhen( clearCnt === 10.U ){
isLock := false.B
}
val asyncSerDat =
Mux1H(
(for { i <- 0 until 22 } yield {
(arbCali === i.U) -> flitReg(i+(8))
})
)
io.syncSerDat := asyncSerDat
}

View File

@@ -1,117 +1,117 @@
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 encode = Flipped(new Encode_Bundle)
val serDat = Output(Bool())
val flush = Input(Bool())
}
class CDROut extends Module with RequireAsyncReset{
val io: CDROutIO = IO(new CDROutIO)
def PRE_NUM = 3 //PRE_NUM should >= 3
def STATE_IDLE = 0.U
def STATE_PREAMBLE = 1.U
def STATE_PAYLOAD = 2.U
val ETH_PRE = "h68".U(8.W)
val ETH_SFD = "h25".U(8.W)
val stateNext = Wire(UInt(2.W))
val stateCurr = RegNext( stateNext, 0.U )
val bitCnt = RegInit(0.U(4.W))
val byteCnt = RegInit(0.U(3.W)) //payload dont need to count
val shiftData = RegInit(0.U(10.W))
io.encode.isEnable := false.B //组合逻辑
io.encode.dataIn := 0.U //组合逻辑
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 & (
(stateCurr === STATE_PREAMBLE & byteCnt === (PRE_NUM-1).U) |
(stateCurr === STATE_PAYLOAD)
)
// assert( ~(~io.axis.valid & io.axis.ready) )
when( ~io.axis.valid & io.axis.ready ){
printf( "Error, CDROut axis overflow!\n" )
}
when( io.flush ){
shiftData := 0.U
} .elsewhen( stateCurr === STATE_IDLE & stateNext === STATE_PREAMBLE){ //PRE
shiftData := io.encode.dataOut
io.encode.dataIn := ETH_PRE //组合逻辑
io.encode.isEnable := true.B //组合逻辑
} .otherwise{
when( bitCnt =/= 9.U ){
shiftData := shiftData << 1
} .otherwise{ //bitCnt === 9.U
when( stateCurr === STATE_PREAMBLE ){
shiftData := io.encode.dataOut
io.encode.dataIn := MuxCase( ETH_PRE, Array(
( byteCnt === (PRE_NUM-2).U ) -> ETH_SFD,
( byteCnt === (PRE_NUM-1).U ) -> io.axis.bits.tdata,
)) //组合逻辑
io.encode.isEnable := true.B //组合逻辑
} .elsewhen( stateCurr === STATE_PAYLOAD ){
io.encode.dataIn := io.axis.bits.tdata //组合逻辑
shiftData := io.encode.dataOut
io.encode.isEnable := true.B //组合逻辑
}
}
}
when( stateCurr === STATE_IDLE ){ //PRE
bitCnt := 0.U
} .otherwise{
when( bitCnt === 9.U ){
bitCnt := 0.U
} .otherwise{
bitCnt := bitCnt + 1.U
}
}
when( (stateCurr === STATE_IDLE) | (stateCurr === STATE_PAYLOAD) ){
byteCnt := 0.U
} .elsewhen( bitCnt === 9.U ){
byteCnt := byteCnt + 1.U
}
}
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 encode = Flipped(new Encode_Bundle)
val serDat = Output(Bool())
val flush = Input(Bool())
}
class CDROut extends Module with RequireAsyncReset{
val io: CDROutIO = IO(new CDROutIO)
def PRE_NUM = 3 //PRE_NUM should >= 3
def STATE_IDLE = 0.U
def STATE_PREAMBLE = 1.U
def STATE_PAYLOAD = 2.U
val ETH_PRE = "h68".U(8.W)
val ETH_SFD = "h25".U(8.W)
val stateNext = Wire(UInt(2.W))
val stateCurr = RegNext( stateNext, 0.U )
val bitCnt = RegInit(0.U(4.W))
val byteCnt = RegInit(0.U(3.W)) //payload dont need to count
val shiftData = RegInit(0.U(10.W))
io.encode.isEnable := false.B //组合逻辑
io.encode.dataIn := 0.U //组合逻辑
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 & (
(stateCurr === STATE_PREAMBLE & byteCnt === (PRE_NUM-1).U) |
(stateCurr === STATE_PAYLOAD)
)
// assert( ~(~io.axis.valid & io.axis.ready) )
when( ~io.axis.valid & io.axis.ready ){
printf( "Error, CDROut axis overflow!\n" )
}
when( io.flush ){
shiftData := 0.U
} .elsewhen( stateCurr === STATE_IDLE & stateNext === STATE_PREAMBLE){ //PRE
shiftData := io.encode.dataOut
io.encode.dataIn := ETH_PRE //组合逻辑
io.encode.isEnable := true.B //组合逻辑
} .otherwise{
when( bitCnt =/= 9.U ){
shiftData := shiftData << 1
} .otherwise{ //bitCnt === 9.U
when( stateCurr === STATE_PREAMBLE ){
shiftData := io.encode.dataOut
io.encode.dataIn := MuxCase( ETH_PRE, Array(
( byteCnt === (PRE_NUM-2).U ) -> ETH_SFD,
( byteCnt === (PRE_NUM-1).U ) -> io.axis.bits.tdata,
)) //组合逻辑
io.encode.isEnable := true.B //组合逻辑
} .elsewhen( stateCurr === STATE_PAYLOAD ){
io.encode.dataIn := io.axis.bits.tdata //组合逻辑
shiftData := io.encode.dataOut
io.encode.isEnable := true.B //组合逻辑
}
}
}
when( stateCurr === STATE_IDLE ){ //PRE
bitCnt := 0.U
} .otherwise{
when( bitCnt === 9.U ){
bitCnt := 0.U
} .otherwise{
bitCnt := bitCnt + 1.U
}
}
when( (stateCurr === STATE_IDLE) | (stateCurr === STATE_PAYLOAD) ){
byteCnt := 0.U
} .elsewhen( bitCnt === 9.U ){
byteCnt := byteCnt + 1.U
}
}

View File

@@ -1,33 +1,33 @@
package BACK
import chisel3._
import chisel3.util._
class Encryptor_IO_Bundle extends Bundle{
val init = Flipped(Valid(UInt(128.W)))
val op = Decoupled(UInt(8.W))
}
class Encryptor extends Module{
val io: Encryptor_IO_Bundle = IO(new Encryptor_IO_Bundle)
val encryptReg = RegInit(0.U(128.W))
when( io.init.valid ){
encryptReg := io.init.bits
} .elsewhen( io.op.fire ){
encryptReg := Cat(encryptReg(119,0), io.op.bits)
}
val opValid = RegInit(false.B)
when( io.init.fire ){
opValid := true.B
}
io.op.valid := opValid
io.op.bits := encryptReg(127, 120)
}
package BACK
import chisel3._
import chisel3.util._
class Encryptor_IO_Bundle extends Bundle{
val init = Flipped(Valid(UInt(128.W)))
val op = Decoupled(UInt(8.W))
}
class Encryptor extends Module{
val io: Encryptor_IO_Bundle = IO(new Encryptor_IO_Bundle)
val encryptReg = RegInit(0.U(128.W))
when( io.init.valid ){
encryptReg := io.init.bits
} .elsewhen( io.op.fire ){
encryptReg := Cat(encryptReg(119,0), io.op.bits)
}
val opValid = RegInit(false.B)
when( io.init.fire ){
opValid := true.B
}
io.op.valid := opValid
io.op.bits := encryptReg(127, 120)
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,210 +1,210 @@
package BACK
import chisel3._
import chisel3.util._
class MasterParserIO extends Bundle{
val downOut = Decoupled(new AXIS_Bundle(8))
val upIn = Flipped( Decoupled(new AXIS_Bundle(8)) )
val sram_w = Flipped(new SRAM2kWRIO)
val sram_r = Flipped(new SRAM2kRDIO)
val req = Input(Bool())
val rsp = Valid(new Bundle{
val isError = Bool()
})
val rxEnq = Output( Bool())
val txDeq = Output( Bool())
val cReg = Input(new CommonRegisterBundle)
val mReg = Input(new MasterRegisterBundle)
val deltaTimeStamp = Output(UInt(32.W))
val upRecStat = Output(new Stat_IO_Bundle)
}
abstract class MasterParserBase extends Module with RequireAsyncReset{
val io: MasterParserIO = IO(new MasterParserIO)
val txCnt = RegInit(0.U(12.W))
val txLen = RegInit(0.U(11.W))
val txAddr = RegInit(0.U(15.W))
val rxCnt = RegInit(0.U(12.W))
val rxLen = RegInit(0.U(11.W))
val rxAddr = RegInit(0.U(15.W))
val reqReady = RegInit(true.B)
val txcrc = Module(new crc32_8)
val rxcrc = Module(new crc32_8)
when( io.req ){
reqReady := false.B
} .elsewhen( io.downOut.fire & txCnt === txLen + (4-1).U ){
reqReady := true.B
}
when( io.req ){
txLen := Mux1H(Seq(
( io.mReg.txSM === 0.U ) -> io.cReg.smTrigLen(1),
( io.mReg.txSM === 1.U ) -> io.cReg.smTrigLen(3),
( io.mReg.txSM === 2.U ) -> io.cReg.smTrigLen(5),
( io.mReg.txSM === 3.U ) -> io.cReg.smTrigLen(7),
))
rxLen := Mux1H(Seq(
( io.mReg.rxSM === 0.U ) -> io.cReg.smTrigLen(0),
( io.mReg.rxSM === 1.U ) -> io.cReg.smTrigLen(2),
( io.mReg.rxSM === 2.U ) -> io.cReg.smTrigLen(4),
( io.mReg.rxSM === 3.U ) -> io.cReg.smTrigLen(6),
))
txCnt := 0.U
} .elsewhen( io.downOut.fire ){
txCnt := txCnt + 1.U
}
when( io.req ){
txAddr := 0.U
} .elsewhen( io.downOut.fire ){
txAddr := txAddr + 1.U
}
when( io.req ){
rxAddr := 0.U
} .elsewhen( io.upIn.fire ){
rxAddr := rxAddr + 1.U
}
io.sram_r.enr :=
io.req | io.downOut.fire
io.sram_r.addrr := Mux( io.req, 0.U, txAddr + 1.U )
io.downOut.valid := ~reqReady
val isRplTimeStamp = io.mReg.rplTimeStampTx.extract(15)
val isRplDeltaStamp = io.mReg.rplTimeStampTx.extract(14)
val rplCnt0 = io.mReg.rplTimeStampTx(10,0) + 0.U
val rplCnt1 = io.mReg.rplTimeStampTx(10,0) + 1.U
val rplCnt2 = io.mReg.rplTimeStampTx(10,0) + 2.U
val rplCnt3 = io.mReg.rplTimeStampTx(10,0) + 3.U
val rplCnt4 = io.mReg.rplTimeStampTx(10,0) + 4.U
val rplCnt5 = io.mReg.rplTimeStampTx(10,0) + 5.U
val rplCnt6 = io.mReg.rplTimeStampTx(10,0) + 6.U
val rplCnt7 = io.mReg.rplTimeStampTx(10,0) + 7.U
val rplCnt8 = io.mReg.rplTimeStampTx(10,0) + 8.U
val rplCnt9 = io.mReg.rplTimeStampTx(10,0) + 9.U
val rplCnt10 = io.mReg.rplTimeStampTx(10,0) + 10.U
val rplCnt11 = io.mReg.rplTimeStampTx(10,0) + 11.U
io.downOut.bits.tdata := Mux1H(Seq(
( txCnt < txLen ) ->
MuxCase( io.sram_r.datar, Array(
( isRplTimeStamp & ( txCnt === rplCnt0 ) ) -> RegEnable(io.cReg.recoTimeStamp(7,0), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt1 ) ) -> RegEnable(io.cReg.recoTimeStamp(15,8), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt2 ) ) -> RegEnable(io.cReg.recoTimeStamp(23,16), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt3 ) ) -> RegEnable(io.cReg.recoTimeStamp(31,24), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt4 ) ) -> RegEnable(io.cReg.recoTimeStamp(39,32), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt5 ) ) -> RegEnable(io.cReg.recoTimeStamp(47,40), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt6 ) ) -> RegEnable(io.cReg.recoTimeStamp(55,48), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt7 ) ) -> RegEnable(io.cReg.recoTimeStamp(63,56), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplDeltaStamp & ( txCnt === rplCnt8 ) ) -> io.cReg.mstDeltaTime(7,0),
( isRplDeltaStamp & ( txCnt === rplCnt9 ) ) -> io.cReg.mstDeltaTime(15,8),
( isRplDeltaStamp & ( txCnt === rplCnt10 ) ) -> io.cReg.mstDeltaTime(23,16),
( isRplDeltaStamp & ( txCnt === rplCnt11 ) ) -> io.cReg.mstDeltaTime(31,24),
)),
( txCnt === txLen + 0.U ) -> txcrc.io.crc(31,24),
( txCnt === txLen + 1.U ) -> txcrc.io.crc(23,16),
( txCnt === txLen + 2.U ) -> txcrc.io.crc(15, 8),
( txCnt === txLen + 3.U ) -> txcrc.io.crc( 7, 0),
))
io.downOut.bits.tuser := false.B
io.downOut.bits.tlast := txCnt === (txLen + 3.U)
val recCrcCheck = RegInit(0.U(32.W))
when( io.req ){
rxCnt := 0.U
} .elsewhen( io.upIn.fire ){
rxCnt := rxCnt + 1.U
}
io.upIn.ready := true.B
io.sram_w.enw := io.upIn.fire
io.sram_w.addrw := rxAddr
io.sram_w.dataw := io.upIn.bits.tdata
io.rsp.valid := io.upIn.fire & io.upIn.bits.tlast
io.rsp.bits.isError := io.upIn.fire & io.upIn.bits.tlast & (Cat( recCrcCheck(31,8), io.upIn.bits.tdata ) =/= rxcrc.io.crc)
io.rxEnq := io.upIn.fire & io.upIn.bits.tlast
io.txDeq := io.downOut.fire & io.downOut.bits.tlast
txcrc.io.isEnable := io.downOut.fire & txCnt < txLen
txcrc.io.dataIn := io.downOut.bits.tdata
txcrc.io.flush := reqReady
rxcrc.io.isEnable := io.upIn.fire & rxCnt < rxLen
rxcrc.io.dataIn := io.upIn.bits.tdata
rxcrc.io.flush := io.rsp.fire
when( io.upIn.fire ){
when( rxCnt === rxLen ){
recCrcCheck := io.upIn.bits.tdata << 24
} .elsewhen( rxCnt === (rxLen + 1.U) ){
recCrcCheck := Cat( recCrcCheck(31,24), io.upIn.bits.tdata, recCrcCheck(15,0) )
} .elsewhen( rxCnt === (rxLen + 2.U) ){
recCrcCheck := Cat( recCrcCheck(31,16), io.upIn.bits.tdata, recCrcCheck( 7,0) )
} .elsewhen( rxCnt === (rxLen + 3.U) ){
recCrcCheck := Cat( recCrcCheck(31,8), io.upIn.bits.tdata )
}
}
}
trait MasterParserStat{ this: MasterParserBase =>
io.upRecStat.isHeaderError := false.B
io.upRecStat.isSubHeaderError := false.B
io.upRecStat.isPayloadError := false.B
io.upRecStat.isSubTailError := false.B
io.upRecStat.isCRCError := io.rsp.valid & io.rsp.bits.isError
io.upRecStat.isFinish := io.rsp.valid & ~io.rsp.bits.isError
io.upRecStat.isRecByteAck := io.upIn.fire
}
class MasterParser extends MasterParserBase
with MasterParserStat{
val deltaTimeStamp = RegInit(0.U(32.W))
// dontTouch(deltaTimeStamp)
io.deltaTimeStamp := deltaTimeStamp
val txStamps = RegInit(0.U(32.W))
val pkgChkCnt = RegInit(0.U(4.W))
when( io.upIn.fire & io.upIn.bits.tlast ){
pkgChkCnt := 0.U
} .elsewhen( io.downOut.fire & pkgChkCnt =/= 9.U ){
pkgChkCnt := pkgChkCnt + 1.U
}
when( io.downOut.fire & io.downOut.bits.tlast ){
txStamps := io.cReg.timeStamp(31,0)
} .elsewhen( io.upIn.fire & io.upIn.bits.tlast & ~io.upIn.bits.tuser & pkgChkCnt === 9.U ){
deltaTimeStamp := io.cReg.timeStamp(31,0) - txStamps
}
package BACK
import chisel3._
import chisel3.util._
class MasterParserIO extends Bundle{
val downOut = Decoupled(new AXIS_Bundle(8))
val upIn = Flipped( Decoupled(new AXIS_Bundle(8)) )
val sram_w = Flipped(new SRAM2kWRIO)
val sram_r = Flipped(new SRAM2kRDIO)
val req = Input(Bool())
val rsp = Valid(new Bundle{
val isError = Bool()
})
val rxEnq = Output( Bool())
val txDeq = Output( Bool())
val cReg = Input(new CommonRegisterBundle)
val mReg = Input(new MasterRegisterBundle)
val deltaTimeStamp = Output(UInt(32.W))
val upRecStat = Output(new Stat_IO_Bundle)
}
abstract class MasterParserBase extends Module with RequireAsyncReset{
val io: MasterParserIO = IO(new MasterParserIO)
val txCnt = RegInit(0.U(12.W))
val txLen = RegInit(0.U(11.W))
val txAddr = RegInit(0.U(15.W))
val rxCnt = RegInit(0.U(12.W))
val rxLen = RegInit(0.U(11.W))
val rxAddr = RegInit(0.U(15.W))
val reqReady = RegInit(true.B)
val txcrc = Module(new crc32_8)
val rxcrc = Module(new crc32_8)
when( io.req ){
reqReady := false.B
} .elsewhen( io.downOut.fire & txCnt === txLen + (4-1).U ){
reqReady := true.B
}
when( io.req ){
txLen := Mux1H(Seq(
( io.mReg.txSM === 0.U ) -> io.cReg.smTrigLen(1),
( io.mReg.txSM === 1.U ) -> io.cReg.smTrigLen(3),
( io.mReg.txSM === 2.U ) -> io.cReg.smTrigLen(5),
( io.mReg.txSM === 3.U ) -> io.cReg.smTrigLen(7),
))
rxLen := Mux1H(Seq(
( io.mReg.rxSM === 0.U ) -> io.cReg.smTrigLen(0),
( io.mReg.rxSM === 1.U ) -> io.cReg.smTrigLen(2),
( io.mReg.rxSM === 2.U ) -> io.cReg.smTrigLen(4),
( io.mReg.rxSM === 3.U ) -> io.cReg.smTrigLen(6),
))
txCnt := 0.U
} .elsewhen( io.downOut.fire ){
txCnt := txCnt + 1.U
}
when( io.req ){
txAddr := 0.U
} .elsewhen( io.downOut.fire ){
txAddr := txAddr + 1.U
}
when( io.req ){
rxAddr := 0.U
} .elsewhen( io.upIn.fire ){
rxAddr := rxAddr + 1.U
}
io.sram_r.enr :=
io.req | io.downOut.fire
io.sram_r.addrr := Mux( io.req, 0.U, txAddr + 1.U )
io.downOut.valid := ~reqReady
val isRplTimeStamp = io.mReg.rplTimeStampTx.extract(15)
val isRplDeltaStamp = io.mReg.rplTimeStampTx.extract(14)
val rplCnt0 = io.mReg.rplTimeStampTx(10,0) + 0.U
val rplCnt1 = io.mReg.rplTimeStampTx(10,0) + 1.U
val rplCnt2 = io.mReg.rplTimeStampTx(10,0) + 2.U
val rplCnt3 = io.mReg.rplTimeStampTx(10,0) + 3.U
val rplCnt4 = io.mReg.rplTimeStampTx(10,0) + 4.U
val rplCnt5 = io.mReg.rplTimeStampTx(10,0) + 5.U
val rplCnt6 = io.mReg.rplTimeStampTx(10,0) + 6.U
val rplCnt7 = io.mReg.rplTimeStampTx(10,0) + 7.U
val rplCnt8 = io.mReg.rplTimeStampTx(10,0) + 8.U
val rplCnt9 = io.mReg.rplTimeStampTx(10,0) + 9.U
val rplCnt10 = io.mReg.rplTimeStampTx(10,0) + 10.U
val rplCnt11 = io.mReg.rplTimeStampTx(10,0) + 11.U
io.downOut.bits.tdata := Mux1H(Seq(
( txCnt < txLen ) ->
MuxCase( io.sram_r.datar, Array(
( isRplTimeStamp & ( txCnt === rplCnt0 ) ) -> RegEnable(io.cReg.recoTimeStamp(7,0), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt1 ) ) -> RegEnable(io.cReg.recoTimeStamp(15,8), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt2 ) ) -> RegEnable(io.cReg.recoTimeStamp(23,16), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt3 ) ) -> RegEnable(io.cReg.recoTimeStamp(31,24), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt4 ) ) -> RegEnable(io.cReg.recoTimeStamp(39,32), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt5 ) ) -> RegEnable(io.cReg.recoTimeStamp(47,40), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt6 ) ) -> RegEnable(io.cReg.recoTimeStamp(55,48), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplTimeStamp & ( txCnt === rplCnt7 ) ) -> RegEnable(io.cReg.recoTimeStamp(63,56), 0.U(8.W), io.downOut.fire & txCnt === 0.U ),
( isRplDeltaStamp & ( txCnt === rplCnt8 ) ) -> io.cReg.mstDeltaTime(7,0),
( isRplDeltaStamp & ( txCnt === rplCnt9 ) ) -> io.cReg.mstDeltaTime(15,8),
( isRplDeltaStamp & ( txCnt === rplCnt10 ) ) -> io.cReg.mstDeltaTime(23,16),
( isRplDeltaStamp & ( txCnt === rplCnt11 ) ) -> io.cReg.mstDeltaTime(31,24),
)),
( txCnt === txLen + 0.U ) -> txcrc.io.crc(31,24),
( txCnt === txLen + 1.U ) -> txcrc.io.crc(23,16),
( txCnt === txLen + 2.U ) -> txcrc.io.crc(15, 8),
( txCnt === txLen + 3.U ) -> txcrc.io.crc( 7, 0),
))
io.downOut.bits.tuser := false.B
io.downOut.bits.tlast := txCnt === (txLen + 3.U)
val recCrcCheck = RegInit(0.U(32.W))
when( io.req ){
rxCnt := 0.U
} .elsewhen( io.upIn.fire ){
rxCnt := rxCnt + 1.U
}
io.upIn.ready := true.B
io.sram_w.enw := io.upIn.fire
io.sram_w.addrw := rxAddr
io.sram_w.dataw := io.upIn.bits.tdata
io.rsp.valid := io.upIn.fire & io.upIn.bits.tlast
io.rsp.bits.isError := io.upIn.fire & io.upIn.bits.tlast & (Cat( recCrcCheck(31,8), io.upIn.bits.tdata ) =/= rxcrc.io.crc)
io.rxEnq := io.upIn.fire & io.upIn.bits.tlast
io.txDeq := io.downOut.fire & io.downOut.bits.tlast
txcrc.io.isEnable := io.downOut.fire & txCnt < txLen
txcrc.io.dataIn := io.downOut.bits.tdata
txcrc.io.flush := reqReady
rxcrc.io.isEnable := io.upIn.fire & rxCnt < rxLen
rxcrc.io.dataIn := io.upIn.bits.tdata
rxcrc.io.flush := io.rsp.fire
when( io.upIn.fire ){
when( rxCnt === rxLen ){
recCrcCheck := io.upIn.bits.tdata << 24
} .elsewhen( rxCnt === (rxLen + 1.U) ){
recCrcCheck := Cat( recCrcCheck(31,24), io.upIn.bits.tdata, recCrcCheck(15,0) )
} .elsewhen( rxCnt === (rxLen + 2.U) ){
recCrcCheck := Cat( recCrcCheck(31,16), io.upIn.bits.tdata, recCrcCheck( 7,0) )
} .elsewhen( rxCnt === (rxLen + 3.U) ){
recCrcCheck := Cat( recCrcCheck(31,8), io.upIn.bits.tdata )
}
}
}
trait MasterParserStat{ this: MasterParserBase =>
io.upRecStat.isHeaderError := false.B
io.upRecStat.isSubHeaderError := false.B
io.upRecStat.isPayloadError := false.B
io.upRecStat.isSubTailError := false.B
io.upRecStat.isCRCError := io.rsp.valid & io.rsp.bits.isError
io.upRecStat.isFinish := io.rsp.valid & ~io.rsp.bits.isError
io.upRecStat.isRecByteAck := io.upIn.fire
}
class MasterParser extends MasterParserBase
with MasterParserStat{
val deltaTimeStamp = RegInit(0.U(32.W))
// dontTouch(deltaTimeStamp)
io.deltaTimeStamp := deltaTimeStamp
val txStamps = RegInit(0.U(32.W))
val pkgChkCnt = RegInit(0.U(4.W))
when( io.upIn.fire & io.upIn.bits.tlast ){
pkgChkCnt := 0.U
} .elsewhen( io.downOut.fire & pkgChkCnt =/= 9.U ){
pkgChkCnt := pkgChkCnt + 1.U
}
when( io.downOut.fire & io.downOut.bits.tlast ){
txStamps := io.cReg.timeStamp(31,0)
} .elsewhen( io.upIn.fire & io.upIn.bits.tlast & ~io.upIn.bits.tuser & pkgChkCnt === 9.U ){
deltaTimeStamp := io.cReg.timeStamp(31,0) - txStamps
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,225 +1,227 @@
package BACK
import chisel3._
import chisel3.util._
abstract class SyncSpiInterfaceBase extends Module with RequireAsyncReset{
val io = IO(new RegAccessInterfaceIO)
val qspi = IO(new QSPIInterfaceIO)
val bitSel = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){RegInit(0.U(3.W)) }
val byteSel = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){RegInit(0.U(12.W))}
val exRego = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){RegInit(0.U(8.W))}
val exRegi = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){RegInit(0.U(8.W))}
val addrw_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(0.U(16.W)) } }
val addrr_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(0.U(16.W)) } }
val dataw_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(0.U(8.W)) } }
val isEnR_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(false.B) } }
val isEnW_async = for( _ <- 0 until 2 ) yield { withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(false.B) } }
val spiLen = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(2.U(12.W)) }
val spiLenTemp = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(2.U(12.W)) }
val spiCnt = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(0.U(12.W)) }
val isSpiWrite = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(false.B) }
val isSpiRead = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(false.B) }
val isPing_async = withClockAndReset((~qspi.sck).asClock, qspi.csn.asAsyncReset){ RegInit(false.B) }
val isPong_sync = RegInit(false.B)
val isEnW_sync = for( i <- 0 until 2 ) yield { ShiftRegisters( isEnW_async(i), 3, false.B, true.B ) }
val isEnR_sync = for( i <- 0 until 2 ) yield { ShiftRegisters( isEnR_async(i), 3, false.B, true.B ) }
val datar_sync = for( _ <- 0 until 2 ) yield { RegInit(0.U(8.W)) }
val isEnW = for( i <- 0 until 2 ) yield { ~isEnW_sync(i)(2) & isEnW_sync(i)(1) }
val isEnR = for( i <- 0 until 2 ) yield { ~isEnR_sync(i)(2) & isEnR_sync(i)(1) }
}
trait SyncSpiAsync{ this: SyncSpiInterfaceBase =>
qspi.miso := exRego(7, 4)
qspi.isDirIn := isSpiWrite | (byteSel <= 3.U)
when( true.B ){
bitSel := ~bitSel
}
when( bitSel.andR ){
byteSel := byteSel + 1.U
}
when( bitSel === 0.U ){
exRegi := Cat( 0.U, qspi.mosi )
}.otherwise{
exRegi := Cat( exRegi(3,0), qspi.mosi )
}
when( bitSel.andR ){
when((byteSel === 1.U || byteSel === 2.U ) ){
exRego := 0.U //地址1cmd
} .elsewhen( isSpiRead ){
when( isPing_async ){ //取巧
exRego := datar_sync(0)
} .otherwise{
exRego := datar_sync(1)
}
}
} .otherwise{
exRego := exRego << 4
}
when( isEnR_async(0) | isEnW_async(0) | isEnR_async(1) | isEnW_async(1) ){
spiCnt := spiCnt + 1.U
}
when( byteSel === 2.U & bitSel.andR ){
spiLenTemp := Cat( qspi.mosi, 0.U(8.W) )
} .elsewhen( byteSel === 3.U & bitSel === 0.U ){
spiLenTemp := Cat( spiLenTemp(11, 8), qspi.mosi, 0.U(4.W) )
} .elsewhen( byteSel === 3.U & bitSel.andR ){
spiLen := Cat( spiLenTemp(11, 4), qspi.mosi )
}
when( isEnW_async(0) ){
addrw_async(0) := addrw_async(0) + 2.U
} .elsewhen( isEnW_async(1) ){
addrw_async(1) := addrw_async(1) + 2.U
} .elsewhen( bitSel === 0.U ){
when( byteSel === 1.U ){
addrw_async(0) := exRegi
addrw_async(1) := exRegi
} .elsewhen( byteSel === 2.U ) {
addrw_async(0) := Cat(addrw_async(0)(7,0), exRegi)
addrw_async(1) := Cat(addrw_async(1)(7,0), exRegi) + 1.U
}
}
when( isEnR_async(0) ){
addrr_async(0) := addrr_async(0) + 2.U
} .elsewhen( isEnR_async(1) ){
addrr_async(1) := addrr_async(1) + 2.U
} .elsewhen( bitSel === 0.U ){
when( byteSel === 1.U ){
addrr_async(0) := exRegi
addrr_async(1) := exRegi
} .elsewhen( byteSel === 2.U ) {
addrr_async(0) := Cat(addrr_async(0)(7,0), exRegi)
addrr_async(1) := Cat(addrr_async(1)(7,0), exRegi) + 1.U
}
}
when( byteSel === 2.U & bitSel === 0.U ){ //CS为低且SCK上跳的第0byte
when( qspi.mosi.extract(3) ){
isSpiRead := true.B
} .otherwise{
isSpiWrite := true.B
}
}
when( bitSel.andR ){
when( byteSel >= 4.U & isSpiWrite ){
when( ~isPing_async ){
dataw_async(0) := Cat( exRegi(3,0), qspi.mosi )
} .otherwise{
dataw_async(1) := Cat( exRegi(3,0), qspi.mosi )
}
}
}
when(
(byteSel === 2.U & bitSel === 0.U & (spiCnt <= spiLen) & qspi.mosi === "h8".U) ||
(byteSel > 2.U & bitSel === 0.U & (spiCnt <= spiLen) & isSpiRead)
){
when( ~isPing_async ){
isEnR_async(0) := true.B
} .otherwise{
isEnR_async(1) := true.B
}
} .elsewhen( bitSel.andR ){
isEnR_async(0) := false.B
isEnR_async(1) := false.B
}
when( byteSel >= 4.U & bitSel.andR & (spiCnt < spiLen) & isSpiWrite ){
when( ~isPing_async ){
isEnW_async(0) := true.B
} .otherwise{
isEnW_async(1) := true.B
}
} .elsewhen( bitSel === 0.U ){
isEnW_async(0) := false.B
isEnW_async(1) := false.B
}
when( isEnR_async(0) | isEnW_async(0) ){
assert( ~isPing_async )
isPing_async := true.B
} .elsewhen( isEnR_async(1) | isEnW_async(1) ){
assert( isPing_async )
isPing_async := false.B
}
}
trait SyncSpiSync{ this: SyncSpiInterfaceBase =>
io.isEnW :=
( ~isPong_sync & isEnW(0) ) |
( isPong_sync & isEnW(1) )
io.isEnR :=
( ~isPong_sync & isEnR(0) ) |
( isPong_sync & isEnR(1) )
io.addrw := Mux1H(Seq(
~isPong_sync -> addrw_async(0),
isPong_sync -> addrw_async(1),
))
io.addrr := Mux1H(Seq(
~isPong_sync -> addrr_async(0),
isPong_sync -> addrr_async(1),
))
io.dataw := Mux1H(Seq(
~isPong_sync -> dataw_async(0),
isPong_sync -> dataw_async(1),
))
when( RegNext(io.isEnR, false.B) ){
when( RegNext(~isPong_sync, false.B) ){
datar_sync(0) := io.datar
} .otherwise{
datar_sync(1) := io.datar
}
}
when( ShiftRegister( qspi.csn, 2, false.B, true.B ) ){
isPong_sync := false.B
} .elsewhen( io.isEnR | io.isEnW ){
isPong_sync := ~isPong_sync
}
}
class SyncQSpiInterface extends SyncSpiInterfaceBase
with SyncSpiAsync
with SyncSpiSync{
}
package BACK
import chisel3._
import chisel3.util._
abstract class SyncSpiInterfaceBase extends Module with RequireAsyncReset{
val io = IO(new RegAccessInterfaceIO)
val qspi = IO(new QSPIInterfaceIO)
val negedge_sck = (~qspi.sck).asClock
val bitSel = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){RegInit(0.U(3.W)) }
val byteSel = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){RegInit(0.U(12.W))}
val exRego = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){RegInit(0.U(8.W))}
val exRegi = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){RegInit(0.U(8.W))}
val addrw_async = for( _ <- 0 until 2 ) yield { withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(0.U(16.W)) } }
val addrr_async = for( _ <- 0 until 2 ) yield { withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(0.U(16.W)) } }
val dataw_async = for( _ <- 0 until 2 ) yield { withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(0.U(8.W)) } }
val isEnR_async = for( _ <- 0 until 2 ) yield { withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(false.B) } }
val isEnW_async = for( _ <- 0 until 2 ) yield { withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(false.B) } }
val spiLen = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(2.U(12.W)) }
val spiLenTemp = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(2.U(12.W)) }
val spiCnt = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(0.U(12.W)) }
val isSpiWrite = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(false.B) }
val isSpiRead = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(false.B) }
val isPing_async = withClockAndReset(negedge_sck, qspi.csn.asAsyncReset){ RegInit(false.B) }
val isPong_sync = RegInit(false.B)
val isEnW_sync = for( i <- 0 until 2 ) yield { ShiftRegisters( isEnW_async(i), 3, false.B, true.B ) }
val isEnR_sync = for( i <- 0 until 2 ) yield { ShiftRegisters( isEnR_async(i), 3, false.B, true.B ) }
val datar_sync = for( _ <- 0 until 2 ) yield { RegInit(0.U(8.W)) }
val isEnW = for( i <- 0 until 2 ) yield { ~isEnW_sync(i)(2) & isEnW_sync(i)(1) }
val isEnR = for( i <- 0 until 2 ) yield { ~isEnR_sync(i)(2) & isEnR_sync(i)(1) }
}
trait SyncSpiAsync{ this: SyncSpiInterfaceBase =>
qspi.miso := exRego(7, 4)
qspi.isDirIn := isSpiWrite | (byteSel <= 3.U)
when( true.B ){
bitSel := ~bitSel
}
when( bitSel.andR ){
byteSel := byteSel + 1.U
}
when( bitSel === 0.U ){
exRegi := Cat( 0.U, qspi.mosi )
}.otherwise{
exRegi := Cat( exRegi(3,0), qspi.mosi )
}
when( bitSel.andR ){
when((byteSel === 1.U || byteSel === 2.U ) ){
exRego := 0.U //地址1cmd
} .elsewhen( isSpiRead ){
when( isPing_async ){ //取巧
exRego := datar_sync(0)
} .otherwise{
exRego := datar_sync(1)
}
}
} .otherwise{
exRego := exRego << 4
}
when( isEnR_async(0) | isEnW_async(0) | isEnR_async(1) | isEnW_async(1) ){
spiCnt := spiCnt + 1.U
}
when( byteSel === 2.U & bitSel.andR ){
spiLenTemp := Cat( qspi.mosi, 0.U(8.W) )
} .elsewhen( byteSel === 3.U & bitSel === 0.U ){
spiLenTemp := Cat( spiLenTemp(11, 8), qspi.mosi, 0.U(4.W) )
} .elsewhen( byteSel === 3.U & bitSel.andR ){
spiLen := Cat( spiLenTemp(11, 4), qspi.mosi )
}
when( isEnW_async(0) ){
addrw_async(0) := addrw_async(0) + 2.U
} .elsewhen( isEnW_async(1) ){
addrw_async(1) := addrw_async(1) + 2.U
} .elsewhen( bitSel === 0.U ){
when( byteSel === 1.U ){
addrw_async(0) := exRegi
addrw_async(1) := exRegi
} .elsewhen( byteSel === 2.U ) {
addrw_async(0) := Cat(addrw_async(0)(7,0), exRegi)
addrw_async(1) := Cat(addrw_async(1)(7,0), exRegi) + 1.U
}
}
when( isEnR_async(0) ){
addrr_async(0) := addrr_async(0) + 2.U
} .elsewhen( isEnR_async(1) ){
addrr_async(1) := addrr_async(1) + 2.U
} .elsewhen( bitSel === 0.U ){
when( byteSel === 1.U ){
addrr_async(0) := exRegi
addrr_async(1) := exRegi
} .elsewhen( byteSel === 2.U ) {
addrr_async(0) := Cat(addrr_async(0)(7,0), exRegi)
addrr_async(1) := Cat(addrr_async(1)(7,0), exRegi) + 1.U
}
}
when( byteSel === 2.U & bitSel === 0.U ){ //CS为低且SCK上跳的第0byte
when( qspi.mosi.extract(3) ){
isSpiRead := true.B
} .otherwise{
isSpiWrite := true.B
}
}
when( bitSel.andR ){
when( byteSel >= 4.U & isSpiWrite ){
when( ~isPing_async ){
dataw_async(0) := Cat( exRegi(3,0), qspi.mosi )
} .otherwise{
dataw_async(1) := Cat( exRegi(3,0), qspi.mosi )
}
}
}
when(
(byteSel === 2.U & bitSel === 0.U & (spiCnt <= spiLen) & qspi.mosi === "h8".U) ||
(byteSel > 2.U & bitSel === 0.U & (spiCnt <= spiLen) & isSpiRead)
){
when( ~isPing_async ){
isEnR_async(0) := true.B
} .otherwise{
isEnR_async(1) := true.B
}
} .elsewhen( bitSel.andR ){
isEnR_async(0) := false.B
isEnR_async(1) := false.B
}
when( byteSel >= 4.U & bitSel.andR & (spiCnt < spiLen) & isSpiWrite ){
when( ~isPing_async ){
isEnW_async(0) := true.B
} .otherwise{
isEnW_async(1) := true.B
}
} .elsewhen( bitSel === 0.U ){
isEnW_async(0) := false.B
isEnW_async(1) := false.B
}
when( isEnR_async(0) | isEnW_async(0) ){
assert( ~isPing_async )
isPing_async := true.B
} .elsewhen( isEnR_async(1) | isEnW_async(1) ){
assert( isPing_async )
isPing_async := false.B
}
}
trait SyncSpiSync{ this: SyncSpiInterfaceBase =>
io.isEnW :=
( ~isPong_sync & isEnW(0) ) |
( isPong_sync & isEnW(1) )
io.isEnR :=
( ~isPong_sync & isEnR(0) ) |
( isPong_sync & isEnR(1) )
io.addrw := Mux1H(Seq(
~isPong_sync -> addrw_async(0),
isPong_sync -> addrw_async(1),
))
io.addrr := Mux1H(Seq(
~isPong_sync -> addrr_async(0),
isPong_sync -> addrr_async(1),
))
io.dataw := Mux1H(Seq(
~isPong_sync -> dataw_async(0),
isPong_sync -> dataw_async(1),
))
when( RegNext(io.isEnR, false.B) ){
when( RegNext(~isPong_sync, false.B) ){
datar_sync(0) := io.datar
} .otherwise{
datar_sync(1) := io.datar
}
}
when( ShiftRegister( qspi.csn, 2, false.B, true.B ) ){
isPong_sync := false.B
} .elsewhen( io.isEnR | io.isEnW ){
isPong_sync := ~isPong_sync
}
}
class SyncQSpiInterface extends SyncSpiInterfaceBase
with SyncSpiAsync
with SyncSpiSync{
}

View File

@@ -1,110 +1,110 @@
package BACK
import chisel3._
import chisel3.util._
class SRAM2kWRIO extends Bundle {
val addrw = Input(UInt(11.W))
val dataw = Input( UInt(8.W) )
val enw = Input(Bool())
}
class SRAM2kRDIO extends Bundle {
val addrr = Input(UInt(11.W))
val datar = Output( UInt(8.W) )
val enr = Input(Bool())
}
class SRAM2kIO extends Bundle {
val rd = new SRAM2kRDIO
val wr = new SRAM2kWRIO
}
class SMUnitIO(depth: Int) extends Bundle {
val sram_w = new SRAM2kWRIO
val sram_r = new SRAM2kRDIO
val enq = Input(Bool())
val deq = Input(Bool())
val sram = Flipped(Vec(depth, new SRAM2kIO))
val cnt = Output(UInt(8.W))
val flush = Input(Bool())
val isComf = Input(Bool())
val isAbrt = Input(Bool())
}
abstract class SMUnitBase(depth: Int = 4) extends Module with RequireAsyncReset{
val io: SMUnitIO = IO(new SMUnitIO(depth))
val wPtr = RegInit(0.U((log2Ceil(depth)+1).W))
val rPtr = RegInit(0.U((log2Ceil(depth)+1).W))
val cPtr = RegInit(0.U((log2Ceil(depth)+1).W))
val isFull = (wPtr ^ rPtr) === (1.U << log2Ceil(depth))
val isEmpty = ( cPtr === rPtr )
when(io.flush){
wPtr := 0.U
} .elsewhen( io.enq & ~isFull ){
wPtr := wPtr + 1.U
// assert( ~isFull)
} .elsewhen( io.isAbrt ){
wPtr := cPtr
}
when(io.flush){
rPtr := 0.U
} .elsewhen( io.deq & ~isEmpty ){
rPtr := rPtr + 1.U
// assert( ~isEmpty )
}
for( i <- 0 until depth ){
io.sram(i).wr.addrw := 0.U
io.sram(i).wr.dataw := 0.U
io.sram(i).wr.enw := false.B
io.sram(i).rd.addrr := 0.U
io.sram(i).rd.enr := false.B
}
for( i <- 0 until depth ){
when( (wPtr(log2Ceil(depth)-1, 0)) === i.U & ~isFull ){
io.sram(i).wr <> io.sram_w
}
when( (rPtr(log2Ceil(depth)-1, 0)) === i.U & ~isEmpty){
io.sram(i).rd.addrr := io.sram_r.addrr
io.sram(i).rd.enr := io.sram_r.enr
}
}
io.sram_r.datar := Mux1H( ( 0 until depth).map{ i =>
( (rPtr(log2Ceil(depth)-1, 0)) === i.U ) -> io.sram(i).rd.datar
})
io.cnt := cPtr - rPtr
when( io.flush ){
cPtr := 0.U
} .elsewhen( io.isComf ){
cPtr := wPtr
}
}
class SMUnit(depth: Int = 4) extends SMUnitBase(depth) {
}
package BACK
import chisel3._
import chisel3.util._
class SRAM2kWRIO extends Bundle {
val addrw = Input(UInt(11.W))
val dataw = Input( UInt(8.W) )
val enw = Input(Bool())
}
class SRAM2kRDIO extends Bundle {
val addrr = Input(UInt(11.W))
val datar = Output( UInt(8.W) )
val enr = Input(Bool())
}
class SRAM2kIO extends Bundle {
val rd = new SRAM2kRDIO
val wr = new SRAM2kWRIO
}
class SMUnitIO(depth: Int) extends Bundle {
val sram_w = new SRAM2kWRIO
val sram_r = new SRAM2kRDIO
val enq = Input(Bool())
val deq = Input(Bool())
val sram = Flipped(Vec(depth, new SRAM2kIO))
val cnt = Output(UInt(8.W))
val flush = Input(Bool())
val isComf = Input(Bool())
val isAbrt = Input(Bool())
}
abstract class SMUnitBase(depth: Int = 4) extends Module with RequireAsyncReset{
val io: SMUnitIO = IO(new SMUnitIO(depth))
val wPtr = RegInit(0.U((log2Ceil(depth)+1).W))
val rPtr = RegInit(0.U((log2Ceil(depth)+1).W))
val cPtr = RegInit(0.U((log2Ceil(depth)+1).W))
val isFull = (wPtr ^ rPtr) === (1.U << log2Ceil(depth))
val isEmpty = ( cPtr === rPtr )
when(io.flush){
wPtr := 0.U
} .elsewhen( io.enq & ~isFull ){
wPtr := wPtr + 1.U
// assert( ~isFull)
} .elsewhen( io.isAbrt ){
wPtr := cPtr
}
when(io.flush){
rPtr := 0.U
} .elsewhen( io.deq & ~isEmpty ){
rPtr := rPtr + 1.U
// assert( ~isEmpty )
}
for( i <- 0 until depth ){
io.sram(i).wr.addrw := 0.U
io.sram(i).wr.dataw := 0.U
io.sram(i).wr.enw := false.B
io.sram(i).rd.addrr := 0.U
io.sram(i).rd.enr := false.B
}
for( i <- 0 until depth ){
when( (wPtr(log2Ceil(depth)-1, 0)) === i.U & ~isFull ){
io.sram(i).wr <> io.sram_w
}
when( (rPtr(log2Ceil(depth)-1, 0)) === i.U & ~isEmpty){
io.sram(i).rd.addrr := io.sram_r.addrr
io.sram(i).rd.enr := io.sram_r.enr
}
}
io.sram_r.datar := Mux1H( ( 0 until depth).map{ i =>
( (rPtr(log2Ceil(depth)-1, 0)) === i.U ) -> io.sram(i).rd.datar
})
io.cnt := cPtr - rPtr
when( io.flush ){
cPtr := 0.U
} .elsewhen( io.isComf ){
cPtr := wPtr
}
}
class SMUnit(depth: Int = 4) extends SMUnitBase(depth) {
}

View File

@@ -1,66 +1,66 @@
package BACK
import chisel3._
import chisel3.util._
class ShareSRAM2k extends BlackBox with HasBlackBoxInline {
class ShareSRAM2kIO extends Bundle{
val dataw = Input( UInt(8.W) )
val addrw = Input(UInt(15.W))
val enw = Input(Bool())
val datar = Output( UInt(8.W) )
val addrr = Input(UInt(15.W))
val enr = Input(Bool())
val clockr = Input(Bool())
val clockw = Input(Bool())
}
val io: ShareSRAM2kIO = IO(new ShareSRAM2kIO)
setInline("ShareSRAM2k.v",
"""
| module ShareSRAM2k(
| input [7:0] dataw,
| input [14:0] addrw,
| input enw,
|
| output [7:0] datar,
| input [14:0] addrr,
| input enr,
|
| input clockr,
| input clockw
| );
|
| reg [7:0] ram[0:2047];
| reg [7:0] data_r_reg;
|
| always @(posedge clockw) begin
| if(enw) begin
| ram[addrw] <= #1 dataw;
| end
| end
|
| always @(posedge clockr) begin
| if(enr) begin
| data_r_reg <= #1 ram[addrr];
| end
| end
|
| assign datar = data_r_reg;
|
| initial begin
| for ( integer i = 0; i < 2048; i = i + 1 ) begin
| ram[i] = $random;
| end
|
| data_r_reg = $random;
| end
|
| endmodule
""".stripMargin)
package BACK
import chisel3._
import chisel3.util._
class ShareSRAM2k extends BlackBox with HasBlackBoxInline {
class ShareSRAM2kIO extends Bundle{
val dataw = Input( UInt(8.W) )
val addrw = Input(UInt(15.W))
val enw = Input(Bool())
val datar = Output( UInt(8.W) )
val addrr = Input(UInt(15.W))
val enr = Input(Bool())
val clockr = Input(Bool())
val clockw = Input(Bool())
}
val io: ShareSRAM2kIO = IO(new ShareSRAM2kIO)
setInline("ShareSRAM2k.v",
"""
| module ShareSRAM2k(
| input [7:0] dataw,
| input [14:0] addrw,
| input enw,
|
| output [7:0] datar,
| input [14:0] addrr,
| input enr,
|
| input clockr,
| input clockw
| );
|
| reg [7:0] ram[0:2047];
| reg [7:0] data_r_reg;
|
| always @(posedge clockw) begin
| if(enw) begin
| ram[addrw] <= #1 dataw;
| end
| end
|
| always @(posedge clockr) begin
| if(enr) begin
| data_r_reg <= #1 ram[addrr];
| end
| end
|
| assign datar = data_r_reg;
|
| initial begin
| for ( integer i = 0; i < 2048; i = i + 1 ) begin
| ram[i] = $random;
| end
|
| data_r_reg = $random;
| end
|
| endmodule
""".stripMargin)
}

View File

@@ -1,64 +1,64 @@
package BACK
import chisel3._
import chisel3.util._
import chisel3.experimental.dataview._
class ShinTopIO extends TopBase_IO_Bundle{
val multiCLK = Input(Vec(16, Bool()))
val multiCLKDiv4 = Input(Vec(4, Bool()))
}
class ShinTop extends Module with RequireAsyncReset{
val io: ShinTopIO = IO(new ShinTopIO)
val mstSlvSwitch = Module(new MstSlvSwitch)
{
val downCDRInSampleA = Module(new CDRInMultiSample(clkNum = 16))
val upCDRInSampleA = Module(new CDRInMultiSample(clkNum = 16))
downCDRInSampleA.multiCLK := io.multiCLK
upCDRInSampleA.multiCLK := io.multiCLK
downCDRInSampleA.io <> mstSlvSwitch.io.downCDRSampleIn(0)
upCDRInSampleA.io <> mstSlvSwitch.io.upCDRSampleIn(0)
}
{
val downCDRInSampleB = Module(new CDRInMultiSample(clkNum = 4))
val upCDRInSampleB = Module(new CDRInMultiSample(clkNum = 4))
downCDRInSampleB.multiCLK := io.multiCLKDiv4
upCDRInSampleB.multiCLK := io.multiCLKDiv4
downCDRInSampleB.io <> mstSlvSwitch.io.downCDRSampleIn(1)
upCDRInSampleB.io <> mstSlvSwitch.io.upCDRSampleIn(1)
}
{
val downCDRInSampleC = Module(new CDRInOriSample)
val upCDRInSampleC = Module(new CDRInOriSample)
downCDRInSampleC.multiCLK := io.multiCLK
upCDRInSampleC.multiCLK := io.multiCLK
downCDRInSampleC.io <> mstSlvSwitch.io.downCDRSampleIn(2)
upCDRInSampleC.io <> mstSlvSwitch.io.upCDRSampleIn(2)
}
io.viewAsSupertype(new TopBase_IO_Bundle) <> mstSlvSwitch.io.viewAsSupertype(new TopBase_IO_Bundle)
}
package BACK
import chisel3._
import chisel3.util._
import chisel3.experimental.dataview._
class ShinTopIO extends TopBase_IO_Bundle{
val multiCLK = Input(Vec(16, Bool()))
val multiCLKDiv4 = Input(Vec(4, Bool()))
}
class ShinTop extends Module with RequireAsyncReset{
val io: ShinTopIO = IO(new ShinTopIO)
val mstSlvSwitch = Module(new MstSlvSwitch)
{
val downCDRInSampleA = Module(new CDRInMultiSample(clkNum = 16))
val upCDRInSampleA = Module(new CDRInMultiSample(clkNum = 16))
downCDRInSampleA.multiCLK := io.multiCLK
upCDRInSampleA.multiCLK := io.multiCLK
downCDRInSampleA.io <> mstSlvSwitch.io.downCDRSampleIn(0)
upCDRInSampleA.io <> mstSlvSwitch.io.upCDRSampleIn(0)
}
{
val downCDRInSampleB = Module(new CDRInMultiSample(clkNum = 4))
val upCDRInSampleB = Module(new CDRInMultiSample(clkNum = 4))
downCDRInSampleB.multiCLK := io.multiCLKDiv4
upCDRInSampleB.multiCLK := io.multiCLKDiv4
downCDRInSampleB.io <> mstSlvSwitch.io.downCDRSampleIn(1)
upCDRInSampleB.io <> mstSlvSwitch.io.upCDRSampleIn(1)
}
{
val downCDRInSampleC = Module(new CDRInOriSample)
val upCDRInSampleC = Module(new CDRInOriSample)
downCDRInSampleC.multiCLK := io.multiCLK
upCDRInSampleC.multiCLK := io.multiCLK
downCDRInSampleC.io <> mstSlvSwitch.io.downCDRSampleIn(2)
upCDRInSampleC.io <> mstSlvSwitch.io.upCDRSampleIn(2)
}
io.viewAsSupertype(new TopBase_IO_Bundle) <> mstSlvSwitch.io.viewAsSupertype(new TopBase_IO_Bundle)
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,211 +1,211 @@
package BACK
import chisel3._
import chisel3.util._
class SlaveRecParserIO extends Bundle{
val rec = Flipped( Decoupled(new AXIS_Bundle(8)) )
val data = Decoupled(UInt(8.W))
val stateNext = Output(UInt(4.W))
val stateCurr = Output(UInt(4.W))
val frameReq = Valid( new FrameHeader )
val subMsgHeadReq = Valid( new SubMsgHeader )
val subMsgTailReq = Valid( new SubMsgTail )
val isError = Output(Bool())
val stat = Output(new Stat_IO_Bundle)
val flush = Input(Bool())
}
class SlaveRecParser extends Module with RequireAsyncReset{
val io: SlaveRecParserIO = IO(new SlaveRecParserIO)
val crc = Module(new crc32_8)
val STATE_IDLE = 0.U //空闲
val STATE_HEADER = 1.U //长度/ /保留2bits //包类型
val STATE_SUBMSG_HEADER = 2.U //子报文设备索引 //子报文类型
val STATE_PAYLOAD_DATA = 3.U //子报文数据
val STATE_SUBMSG_TAIL = 4.U
val STATE_CRC = 5.U //CRC校验
val STATE_ERROR = 6.U //
val stateNext = Wire(UInt(4.W)); io.stateNext := stateNext
val stateCurr = RegNext(stateNext, STATE_IDLE); io.stateCurr := stateCurr
io.isError := stateCurr === STATE_ERROR
io.rec.ready := stateCurr =/= STATE_IDLE
crc.io.isEnable := io.rec.fire & (
stateCurr === STATE_HEADER |
stateCurr === STATE_SUBMSG_HEADER |
stateCurr === STATE_PAYLOAD_DATA |
stateCurr === STATE_SUBMSG_TAIL
)
crc.io.dataIn := io.rec.bits.tdata
crc.io.flush := stateCurr === STATE_IDLE | io.flush
val crcData = RegInit(0.U(32.W))
val isCrcPass = crc.io.crc === Cat( crcData(23,0), io.rec.bits.tdata )
when( io.rec.fire & stateCurr === STATE_CRC ){
crcData := Cat( crcData(23,0), io.rec.bits.tdata )
}
val FRAME_STYLE_COMMON = 0.U
val FRAME_STYLE_PROBE = 1.U
val lengthCnt = RegInit(0.U(12.W)) //动态计数器
val frameLenCnt = RegInit(0.U(12.W)) //帧长度计数
io.frameReq.valid := (stateCurr === STATE_HEADER) & (stateNext === STATE_SUBMSG_HEADER | stateNext === STATE_CRC)
val frameHeader = RegInit(0.U.asTypeOf(new FrameHeader))
io.frameReq.bits.frameLenAim := frameHeader.frameLenAim
io.frameReq.bits.frameStyle := frameHeader.frameStyle
io.frameReq.bits.frameInfo := frameHeader.frameInfo | io.rec.bits.tdata
io.subMsgHeadReq.valid := (stateCurr === STATE_SUBMSG_HEADER) & (stateNext === STATE_PAYLOAD_DATA)
io.subMsgTailReq.valid := (stateCurr === STATE_SUBMSG_TAIL) & (stateNext =/= STATE_SUBMSG_TAIL)
val subMsgHeader = RegInit(0.U.asTypeOf(new SubMsgHeader))
val subMsgTail = RegInit(0.U.asTypeOf(new SubMsgTail))
io.subMsgHeadReq.bits.devIndex := subMsgHeader.devIndex
io.subMsgHeadReq.bits.style := subMsgHeader.style
io.subMsgHeadReq.bits.address := subMsgHeader.address
io.subMsgHeadReq.bits.operator := subMsgHeader.operator
io.subMsgHeadReq.bits.length := subMsgHeader.length | io.rec.bits.tdata(7,0)
io.subMsgTailReq.bits.workCnt := subMsgTail.workCnt | io.rec.bits.tdata(7,0)
when( io.flush ){
lengthCnt := 0.U
} .elsewhen( io.rec.fire ){
when( stateCurr =/= stateNext ){
lengthCnt := 0.U
} .otherwise{
lengthCnt := lengthCnt + 1.U
}
}
when( io.rec.fire ){
when( stateCurr === STATE_HEADER ){
frameLenCnt := 0.U
} .elsewhen(
( stateCurr === STATE_SUBMSG_HEADER ) ||
( stateCurr === STATE_PAYLOAD_DATA ) ||
( stateCurr === STATE_SUBMSG_TAIL )
){
frameLenCnt := frameLenCnt + 1.U
}
}
io.data.valid := io.rec.fire & stateCurr === STATE_PAYLOAD_DATA
io.data.bits := io.rec.bits.tdata
// assert( ~(io.data.valid & ~io.data.ready), "Assert Failed! Receive Data was rejected by fifo!" )
val isDataRejErr = io.data.valid & ~io.data.ready
when( (io.data.valid & ~io.data.ready) ){
printf( "Error! Receive Data was rejected by fifo!\n")
}
when( io.rec.fire ){
when( stateCurr === STATE_HEADER ){
when( lengthCnt === 0.U ){
frameHeader.frameLenAim := io.rec.bits.tdata << 4
} .elsewhen( lengthCnt === 1.U ){
frameHeader.frameLenAim := frameHeader.frameLenAim | io.rec.bits.tdata(7,4)
frameHeader.frameStyle := io.rec.bits.tdata(1,0)
} .elsewhen( lengthCnt === 2.U ){
frameHeader.frameInfo := io.rec.bits.tdata << 8
} .elsewhen( lengthCnt === 3.U ){
frameHeader.frameInfo := frameHeader.frameInfo | io.rec.bits.tdata
}
}
when( stateCurr === STATE_SUBMSG_HEADER ){
when(lengthCnt === 0.U ){
subMsgHeader.devIndex := io.rec.bits.tdata << 6
} .elsewhen( lengthCnt === 1.U ){
subMsgHeader.devIndex := subMsgHeader.devIndex | io.rec.bits.tdata(7,2)
subMsgHeader.style := io.rec.bits.tdata(1,0)
} .elsewhen( lengthCnt === 2.U ){
subMsgHeader.address := io.rec.bits.tdata << 8
} .elsewhen( lengthCnt === 3.U ){
subMsgHeader.address := subMsgHeader.address | io.rec.bits.tdata
} .elsewhen( lengthCnt === 4.U ){
subMsgHeader.operator := io.rec.bits.tdata(7,4)
subMsgHeader.length := io.rec.bits.tdata(3,0) << 8
} .elsewhen( lengthCnt === 5.U ){
subMsgHeader.length := subMsgHeader.length | io.rec.bits.tdata(7,0)
}
}
when( stateCurr === STATE_SUBMSG_TAIL ){
when(lengthCnt === 0.U ){
subMsgTail.workCnt := io.rec.bits.tdata << 8
} .elsewhen( lengthCnt === 1.U ){
subMsgTail.workCnt := subMsgTail.workCnt | io.rec.bits.tdata(7,0)
}
}
}
stateNext :=
Mux( io.flush, STATE_IDLE,
Mux1H(Seq(
//必须使用上升沿触发,以避免前一帧长度超过预期
( stateCurr === STATE_IDLE ) -> Mux( ~RegNext(io.rec.valid, false.B) & 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
),
( 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,
))
)
io.stat.isHeaderError := stateNext === STATE_ERROR & stateCurr === STATE_HEADER
io.stat.isSubHeaderError := stateNext === STATE_ERROR & stateCurr === STATE_SUBMSG_HEADER
io.stat.isPayloadError := stateNext === STATE_ERROR & stateCurr === STATE_PAYLOAD_DATA
io.stat.isSubTailError := stateNext === STATE_ERROR & stateCurr === STATE_SUBMSG_TAIL
io.stat.isCRCError := stateNext === STATE_ERROR & stateCurr === STATE_CRC
io.stat.isFinish := stateNext === STATE_IDLE & stateCurr === STATE_CRC
io.stat.isRecByteAck := io.rec.fire
}
package BACK
import chisel3._
import chisel3.util._
class SlaveRecParserIO extends Bundle{
val rec = Flipped( Decoupled(new AXIS_Bundle(8)) )
val data = Decoupled(UInt(8.W))
val stateNext = Output(UInt(4.W))
val stateCurr = Output(UInt(4.W))
val frameReq = Valid( new FrameHeader )
val subMsgHeadReq = Valid( new SubMsgHeader )
val subMsgTailReq = Valid( new SubMsgTail )
val isError = Output(Bool())
val stat = Output(new Stat_IO_Bundle)
val flush = Input(Bool())
}
class SlaveRecParser extends Module with RequireAsyncReset{
val io: SlaveRecParserIO = IO(new SlaveRecParserIO)
val crc = Module(new crc32_8)
val STATE_IDLE = 0.U //空闲
val STATE_HEADER = 1.U //长度/ /保留2bits //包类型
val STATE_SUBMSG_HEADER = 2.U //子报文设备索引 //子报文类型
val STATE_PAYLOAD_DATA = 3.U //子报文数据
val STATE_SUBMSG_TAIL = 4.U
val STATE_CRC = 5.U //CRC校验
val STATE_ERROR = 6.U //
val stateNext = Wire(UInt(4.W)); io.stateNext := stateNext
val stateCurr = RegNext(stateNext, STATE_IDLE); io.stateCurr := stateCurr
io.isError := stateCurr === STATE_ERROR
io.rec.ready := stateCurr =/= STATE_IDLE
crc.io.isEnable := io.rec.fire & (
stateCurr === STATE_HEADER |
stateCurr === STATE_SUBMSG_HEADER |
stateCurr === STATE_PAYLOAD_DATA |
stateCurr === STATE_SUBMSG_TAIL
)
crc.io.dataIn := io.rec.bits.tdata
crc.io.flush := stateCurr === STATE_IDLE | io.flush
val crcData = RegInit(0.U(32.W))
val isCrcPass = crc.io.crc === Cat( crcData(23,0), io.rec.bits.tdata )
when( io.rec.fire & stateCurr === STATE_CRC ){
crcData := Cat( crcData(23,0), io.rec.bits.tdata )
}
val FRAME_STYLE_COMMON = 0.U
val FRAME_STYLE_PROBE = 1.U
val lengthCnt = RegInit(0.U(12.W)) //动态计数器
val frameLenCnt = RegInit(0.U(12.W)) //帧长度计数
io.frameReq.valid := (stateCurr === STATE_HEADER) & (stateNext === STATE_SUBMSG_HEADER | stateNext === STATE_CRC)
val frameHeader = RegInit(0.U.asTypeOf(new FrameHeader))
io.frameReq.bits.frameLenAim := frameHeader.frameLenAim
io.frameReq.bits.frameStyle := frameHeader.frameStyle
io.frameReq.bits.frameInfo := frameHeader.frameInfo | io.rec.bits.tdata
io.subMsgHeadReq.valid := (stateCurr === STATE_SUBMSG_HEADER) & (stateNext === STATE_PAYLOAD_DATA)
io.subMsgTailReq.valid := (stateCurr === STATE_SUBMSG_TAIL) & (stateNext =/= STATE_SUBMSG_TAIL)
val subMsgHeader = RegInit(0.U.asTypeOf(new SubMsgHeader))
val subMsgTail = RegInit(0.U.asTypeOf(new SubMsgTail))
io.subMsgHeadReq.bits.devIndex := subMsgHeader.devIndex
io.subMsgHeadReq.bits.style := subMsgHeader.style
io.subMsgHeadReq.bits.address := subMsgHeader.address
io.subMsgHeadReq.bits.operator := subMsgHeader.operator
io.subMsgHeadReq.bits.length := subMsgHeader.length | io.rec.bits.tdata(7,0)
io.subMsgTailReq.bits.workCnt := subMsgTail.workCnt | io.rec.bits.tdata(7,0)
when( io.flush ){
lengthCnt := 0.U
} .elsewhen( io.rec.fire ){
when( stateCurr =/= stateNext ){
lengthCnt := 0.U
} .otherwise{
lengthCnt := lengthCnt + 1.U
}
}
when( io.rec.fire ){
when( stateCurr === STATE_HEADER ){
frameLenCnt := 0.U
} .elsewhen(
( stateCurr === STATE_SUBMSG_HEADER ) ||
( stateCurr === STATE_PAYLOAD_DATA ) ||
( stateCurr === STATE_SUBMSG_TAIL )
){
frameLenCnt := frameLenCnt + 1.U
}
}
io.data.valid := io.rec.fire & stateCurr === STATE_PAYLOAD_DATA
io.data.bits := io.rec.bits.tdata
// assert( ~(io.data.valid & ~io.data.ready), "Assert Failed! Receive Data was rejected by fifo!" )
val isDataRejErr = io.data.valid & ~io.data.ready
when( (io.data.valid & ~io.data.ready) ){
printf( "Error! Receive Data was rejected by fifo!\n")
}
when( io.rec.fire ){
when( stateCurr === STATE_HEADER ){
when( lengthCnt === 0.U ){
frameHeader.frameLenAim := io.rec.bits.tdata << 4
} .elsewhen( lengthCnt === 1.U ){
frameHeader.frameLenAim := frameHeader.frameLenAim | io.rec.bits.tdata(7,4)
frameHeader.frameStyle := io.rec.bits.tdata(1,0)
} .elsewhen( lengthCnt === 2.U ){
frameHeader.frameInfo := io.rec.bits.tdata << 8
} .elsewhen( lengthCnt === 3.U ){
frameHeader.frameInfo := frameHeader.frameInfo | io.rec.bits.tdata
}
}
when( stateCurr === STATE_SUBMSG_HEADER ){
when(lengthCnt === 0.U ){
subMsgHeader.devIndex := io.rec.bits.tdata << 6
} .elsewhen( lengthCnt === 1.U ){
subMsgHeader.devIndex := subMsgHeader.devIndex | io.rec.bits.tdata(7,2)
subMsgHeader.style := io.rec.bits.tdata(1,0)
} .elsewhen( lengthCnt === 2.U ){
subMsgHeader.address := io.rec.bits.tdata << 8
} .elsewhen( lengthCnt === 3.U ){
subMsgHeader.address := subMsgHeader.address | io.rec.bits.tdata
} .elsewhen( lengthCnt === 4.U ){
subMsgHeader.operator := io.rec.bits.tdata(7,4)
subMsgHeader.length := io.rec.bits.tdata(3,0) << 8
} .elsewhen( lengthCnt === 5.U ){
subMsgHeader.length := subMsgHeader.length | io.rec.bits.tdata(7,0)
}
}
when( stateCurr === STATE_SUBMSG_TAIL ){
when(lengthCnt === 0.U ){
subMsgTail.workCnt := io.rec.bits.tdata << 8
} .elsewhen( lengthCnt === 1.U ){
subMsgTail.workCnt := subMsgTail.workCnt | io.rec.bits.tdata(7,0)
}
}
}
stateNext :=
Mux( io.flush, STATE_IDLE,
Mux1H(Seq(
//必须使用上升沿触发,以避免前一帧长度超过预期
( stateCurr === STATE_IDLE ) -> Mux( ~RegNext(io.rec.valid, false.B) & 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
),
( 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,
))
)
io.stat.isHeaderError := stateNext === STATE_ERROR & stateCurr === STATE_HEADER
io.stat.isSubHeaderError := stateNext === STATE_ERROR & stateCurr === STATE_SUBMSG_HEADER
io.stat.isPayloadError := stateNext === STATE_ERROR & stateCurr === STATE_PAYLOAD_DATA
io.stat.isSubTailError := stateNext === STATE_ERROR & stateCurr === STATE_SUBMSG_TAIL
io.stat.isCRCError := stateNext === STATE_ERROR & stateCurr === STATE_CRC
io.stat.isFinish := stateNext === STATE_IDLE & stateCurr === STATE_CRC
io.stat.isRecByteAck := io.rec.fire
}

View File

@@ -1,190 +1,190 @@
package BACK
import chisel3._
import chisel3.util._
class SubMsgTxInfo extends SubMsgHeader{
val source = UInt(2.W)
}
class SlaveSendGenIO extends Bundle{
val data = Vec(2, Flipped( Decoupled(UInt(8.W)) ) )
val frameReq = Flipped(Decoupled( new FrameHeader ))
val subMsgHeadReq = Flipped(Decoupled( new SubMsgTxInfo ))
val subMsgTailReq = Flipped(Decoupled( new SubMsgTail ))
val send = Decoupled(new AXIS_Bundle(8))
val stateCurr = Output(UInt(3.W))
val flush = Input(Bool())
}
class SlaveSendGen extends Module with RequireAsyncReset{
val io: SlaveSendGenIO = IO(new SlaveSendGenIO)
val crc = Module(new crc32_8)
val FRAME_STYLE_COMMON = 0.U
val FRAME_STYLE_PROBE = 1.U
val STATE_IDLE = 0.U //空闲
val STATE_FRAME_HEADER = 1.U //长度/ /保留2bits //包类型
val STATE_SUBMSG_HEADER = 2.U
val STATE_SUBMSG_DATA = 3.U
val STATE_SUBMSG_TAIL = 4.U
val STATE_CRC = 5.U //CRC校验
val STATE_WAIT = 6.U
val stateNext = Wire(UInt(3.W))
val stateCurr = RegNext(stateNext, STATE_IDLE); io.stateCurr := stateCurr
crc.io.isEnable := io.send.fire & (
stateCurr === STATE_FRAME_HEADER |
stateCurr === STATE_SUBMSG_HEADER |
stateCurr === STATE_SUBMSG_DATA |
stateCurr === STATE_SUBMSG_TAIL
)
crc.io.flush := stateCurr === STATE_IDLE | io.flush
val frameInfo = RegInit(0.U.asTypeOf(new FrameHeader))
val subMsgHeadInfo = RegInit(0.U.asTypeOf(new SubMsgTxInfo))
val subMsgTailInfo = RegInit(0.U.asTypeOf(new SubMsgTail))
when( io.frameReq.fire ){
frameInfo := io.frameReq.bits
}
when( io.subMsgHeadReq.fire ){
subMsgHeadInfo := io.subMsgHeadReq.bits
}
when( io.subMsgTailReq.fire ){
subMsgTailInfo := io.subMsgTailReq.bits
}
val lengthCnt = RegInit(0.U(12.W))
val frameLenCnt = RegInit(0.U(12.W))
when( io.send.fire ){
when( stateCurr === STATE_FRAME_HEADER ){
frameLenCnt := 0.U
} .elsewhen( stateCurr === STATE_SUBMSG_HEADER || stateCurr === STATE_SUBMSG_DATA || stateCurr === STATE_SUBMSG_TAIL ){
frameLenCnt := frameLenCnt + 1.U
}
}
when( stateCurr =/= stateNext ){
lengthCnt := 0.U
} .elsewhen(io.send.fire){
lengthCnt := lengthCnt + 1.U
}
io.frameReq.ready := true.B
io.subMsgHeadReq.ready := stateCurr =/= STATE_SUBMSG_HEADER & stateNext === STATE_SUBMSG_HEADER
io.subMsgTailReq.ready := stateCurr =/= STATE_SUBMSG_TAIL & stateNext === STATE_SUBMSG_TAIL
assert( ~(io.subMsgTailReq.ready & ~io.subMsgTailReq.valid) )
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_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)
assert( ~(io.data(0).ready & ~io.data(0).valid) )
assert( ~(io.data(1).ready & ~io.data(1).valid) )
io.send.valid :=
(stateCurr === STATE_FRAME_HEADER) |
(stateCurr === STATE_SUBMSG_HEADER) |
(stateCurr === STATE_SUBMSG_DATA & ( (io.data(0).valid & subMsgHeadInfo.source === 0.U) | (io.data(1).valid & subMsgHeadInfo.source === 1.U) )) |
(stateCurr === STATE_SUBMSG_TAIL) |
(stateCurr === STATE_CRC)
val tdata_frame_header = Mux1H(Seq(
(lengthCnt === 0.U) -> frameInfo.frameLenAim(11,4),
(lengthCnt === 1.U) -> Cat( frameInfo.frameLenAim(3,0), 0.U(2.W), frameInfo.frameStyle),
(lengthCnt === 2.U) -> frameInfo.frameInfo(15,8),
(lengthCnt === 3.U) -> frameInfo.frameInfo( 7,0),
))
val tdata_submsg_header = Mux1H(Seq(
(lengthCnt === 0.U) -> subMsgHeadInfo.devIndex(13,6),
(lengthCnt === 1.U) -> Cat( subMsgHeadInfo.devIndex(5,0), subMsgHeadInfo.style),
(lengthCnt === 2.U) -> subMsgHeadInfo.address(15,8),
(lengthCnt === 3.U) -> subMsgHeadInfo.address(7,0),
(lengthCnt === 4.U) -> Cat(subMsgHeadInfo.operator, subMsgHeadInfo.length(11,8)),
(lengthCnt === 5.U) -> subMsgHeadInfo.length(7,0),
))
val tdata_submsg_data = Mux1H(Seq(
(subMsgHeadInfo.source === 0.U) -> io.data(0).bits,
(subMsgHeadInfo.source === 1.U) -> io.data(1).bits,
))
val tdata_submsg_tail = Mux1H(Seq(
(lengthCnt === 0.U) -> subMsgTailInfo.workCnt(15,8),
(lengthCnt === 1.U) -> subMsgTailInfo.workCnt( 7,0),
))
crc.io.dataIn := Mux1H(Seq(
(stateCurr === STATE_FRAME_HEADER) -> tdata_frame_header,
(stateCurr === STATE_SUBMSG_HEADER) -> tdata_submsg_header,
(stateCurr === STATE_SUBMSG_DATA) -> tdata_submsg_data,
(stateCurr === STATE_SUBMSG_TAIL) -> tdata_submsg_tail,
))
val tdata_crc = Mux1H(Seq(
(lengthCnt === 0.U) -> crc.io.crc(31,24),
(lengthCnt === 1.U) -> crc.io.crc(23,16),
(lengthCnt === 2.U) -> crc.io.crc(15, 8),
(lengthCnt === 3.U) -> crc.io.crc( 7, 0),
))
io.send.bits.tdata := Mux1H(Seq(
(stateCurr === STATE_FRAME_HEADER) -> tdata_frame_header,
(stateCurr === STATE_SUBMSG_HEADER) -> tdata_submsg_header,
(stateCurr === STATE_SUBMSG_DATA) -> tdata_submsg_data,
(stateCurr === STATE_SUBMSG_TAIL) -> tdata_submsg_tail,
(stateCurr === STATE_CRC) -> tdata_crc,
))
io.send.bits.tuser := false.B
io.send.bits.tlast := (stateCurr === STATE_CRC & stateNext === STATE_IDLE)
package BACK
import chisel3._
import chisel3.util._
class SubMsgTxInfo extends SubMsgHeader{
val source = UInt(2.W)
}
class SlaveSendGenIO extends Bundle{
val data = Vec(2, Flipped( Decoupled(UInt(8.W)) ) )
val frameReq = Flipped(Decoupled( new FrameHeader ))
val subMsgHeadReq = Flipped(Decoupled( new SubMsgTxInfo ))
val subMsgTailReq = Flipped(Decoupled( new SubMsgTail ))
val send = Decoupled(new AXIS_Bundle(8))
val stateCurr = Output(UInt(3.W))
val flush = Input(Bool())
}
class SlaveSendGen extends Module with RequireAsyncReset{
val io: SlaveSendGenIO = IO(new SlaveSendGenIO)
val crc = Module(new crc32_8)
val FRAME_STYLE_COMMON = 0.U
val FRAME_STYLE_PROBE = 1.U
val STATE_IDLE = 0.U //空闲
val STATE_FRAME_HEADER = 1.U //长度/ /保留2bits //包类型
val STATE_SUBMSG_HEADER = 2.U
val STATE_SUBMSG_DATA = 3.U
val STATE_SUBMSG_TAIL = 4.U
val STATE_CRC = 5.U //CRC校验
val STATE_WAIT = 6.U
val stateNext = Wire(UInt(3.W))
val stateCurr = RegNext(stateNext, STATE_IDLE); io.stateCurr := stateCurr
crc.io.isEnable := io.send.fire & (
stateCurr === STATE_FRAME_HEADER |
stateCurr === STATE_SUBMSG_HEADER |
stateCurr === STATE_SUBMSG_DATA |
stateCurr === STATE_SUBMSG_TAIL
)
crc.io.flush := stateCurr === STATE_IDLE | io.flush
val frameInfo = RegInit(0.U.asTypeOf(new FrameHeader))
val subMsgHeadInfo = RegInit(0.U.asTypeOf(new SubMsgTxInfo))
val subMsgTailInfo = RegInit(0.U.asTypeOf(new SubMsgTail))
when( io.frameReq.fire ){
frameInfo := io.frameReq.bits
}
when( io.subMsgHeadReq.fire ){
subMsgHeadInfo := io.subMsgHeadReq.bits
}
when( io.subMsgTailReq.fire ){
subMsgTailInfo := io.subMsgTailReq.bits
}
val lengthCnt = RegInit(0.U(12.W))
val frameLenCnt = RegInit(0.U(12.W))
when( io.send.fire ){
when( stateCurr === STATE_FRAME_HEADER ){
frameLenCnt := 0.U
} .elsewhen( stateCurr === STATE_SUBMSG_HEADER || stateCurr === STATE_SUBMSG_DATA || stateCurr === STATE_SUBMSG_TAIL ){
frameLenCnt := frameLenCnt + 1.U
}
}
when( stateCurr =/= stateNext ){
lengthCnt := 0.U
} .elsewhen(io.send.fire){
lengthCnt := lengthCnt + 1.U
}
io.frameReq.ready := true.B
io.subMsgHeadReq.ready := stateCurr =/= STATE_SUBMSG_HEADER & stateNext === STATE_SUBMSG_HEADER
io.subMsgTailReq.ready := stateCurr =/= STATE_SUBMSG_TAIL & stateNext === STATE_SUBMSG_TAIL
assert( ~(io.subMsgTailReq.ready & ~io.subMsgTailReq.valid) )
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_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)
assert( ~(io.data(0).ready & ~io.data(0).valid) )
assert( ~(io.data(1).ready & ~io.data(1).valid) )
io.send.valid :=
(stateCurr === STATE_FRAME_HEADER) |
(stateCurr === STATE_SUBMSG_HEADER) |
(stateCurr === STATE_SUBMSG_DATA & ( (io.data(0).valid & subMsgHeadInfo.source === 0.U) | (io.data(1).valid & subMsgHeadInfo.source === 1.U) )) |
(stateCurr === STATE_SUBMSG_TAIL) |
(stateCurr === STATE_CRC)
val tdata_frame_header = Mux1H(Seq(
(lengthCnt === 0.U) -> frameInfo.frameLenAim(11,4),
(lengthCnt === 1.U) -> Cat( frameInfo.frameLenAim(3,0), 0.U(2.W), frameInfo.frameStyle),
(lengthCnt === 2.U) -> frameInfo.frameInfo(15,8),
(lengthCnt === 3.U) -> frameInfo.frameInfo( 7,0),
))
val tdata_submsg_header = Mux1H(Seq(
(lengthCnt === 0.U) -> subMsgHeadInfo.devIndex(13,6),
(lengthCnt === 1.U) -> Cat( subMsgHeadInfo.devIndex(5,0), subMsgHeadInfo.style),
(lengthCnt === 2.U) -> subMsgHeadInfo.address(15,8),
(lengthCnt === 3.U) -> subMsgHeadInfo.address(7,0),
(lengthCnt === 4.U) -> Cat(subMsgHeadInfo.operator, subMsgHeadInfo.length(11,8)),
(lengthCnt === 5.U) -> subMsgHeadInfo.length(7,0),
))
val tdata_submsg_data = Mux1H(Seq(
(subMsgHeadInfo.source === 0.U) -> io.data(0).bits,
(subMsgHeadInfo.source === 1.U) -> io.data(1).bits,
))
val tdata_submsg_tail = Mux1H(Seq(
(lengthCnt === 0.U) -> subMsgTailInfo.workCnt(15,8),
(lengthCnt === 1.U) -> subMsgTailInfo.workCnt( 7,0),
))
crc.io.dataIn := Mux1H(Seq(
(stateCurr === STATE_FRAME_HEADER) -> tdata_frame_header,
(stateCurr === STATE_SUBMSG_HEADER) -> tdata_submsg_header,
(stateCurr === STATE_SUBMSG_DATA) -> tdata_submsg_data,
(stateCurr === STATE_SUBMSG_TAIL) -> tdata_submsg_tail,
))
val tdata_crc = Mux1H(Seq(
(lengthCnt === 0.U) -> crc.io.crc(31,24),
(lengthCnt === 1.U) -> crc.io.crc(23,16),
(lengthCnt === 2.U) -> crc.io.crc(15, 8),
(lengthCnt === 3.U) -> crc.io.crc( 7, 0),
))
io.send.bits.tdata := Mux1H(Seq(
(stateCurr === STATE_FRAME_HEADER) -> tdata_frame_header,
(stateCurr === STATE_SUBMSG_HEADER) -> tdata_submsg_header,
(stateCurr === STATE_SUBMSG_DATA) -> tdata_submsg_data,
(stateCurr === STATE_SUBMSG_TAIL) -> tdata_submsg_tail,
(stateCurr === STATE_CRC) -> tdata_crc,
))
io.send.bits.tuser := false.B
io.send.bits.tlast := (stateCurr === STATE_CRC & stateNext === STATE_IDLE)
}

View File

@@ -1,239 +1,239 @@
package BACK
import chisel3._
import chisel3.util._
class QSPIInterfaceIO extends Bundle{
val sck = Input(Bool())
val mosi = Input(UInt(4.W))
val miso = Output(UInt(4.W))
val isDirIn = Output(Bool())
val csn = Input(Bool())
}
class SSPIInterfaceIO extends Bundle{
val sck = Input(Bool())
val mosi = Input(Bool())
val miso = Output(Bool())
val csn = Input(Bool())
}
class RegAccessInterfaceIO extends Bundle{
val addrw = Output(UInt(16.W))
val addrr = Output(UInt(16.W))
val dataw = Output( UInt(8.W) )
val datar = Input( UInt(8.W) )
val isEnW = Output(Bool())
val isEnR = Output(Bool())
}
abstract class SpiInterfaceBase extends Module with RequireAsyncReset{
val io = IO(new RegAccessInterfaceIO)
val sck = Wire(Bool())
val csn = Wire(Bool())
//数据信号相对SCK的稳定应该由外部主机保证因此认为SCK采样时刻数据都是稳定正确的
val shiftSCK = ShiftRegisters(sck, 3, false.B, true.B)
val shiftCSn = ShiftRegisters(csn, 3, true.B, true.B)
val isSckPosedge = ~shiftSCK(2) & shiftSCK(1)
val isSckNegedge = shiftSCK(2) & ~shiftSCK(1)
val isSckPosedgeNext = ShiftRegisters(isSckPosedge, 2, false.B, true.B)
val exRego = RegInit(0.U(8.W))
val exRegi = RegInit(0.U(8.W))
val addrw = RegInit(0.U(16.W))
val addrr = RegInit(0.U(16.W))
val spiCmd = RegInit(0.U(1.W))
val isSpiWrite = spiCmd === 0.U
val isSpiRead = spiCmd === 1.U
val bitSel = RegInit(0.U(3.W))
val bitSelNext = RegNext(bitSel, 0.U(3.W))
val byteSel = RegInit(0.U(12.W))
val byteSelNext = RegNext(byteSel, 0.U(12.W))
io.isEnW := isSckPosedgeNext(0) & ~shiftCSn(2) & bitSelNext.andR & isSpiWrite & byteSelNext >= 3.U
io.dataw := exRegi
io.addrr := addrr
io.addrw := addrw
when( shiftCSn(2) & ~shiftCSn(1) ){
byteSel := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
when( bitSel.andR ){
byteSel := byteSel + 1.U
}
}
}
class SSpiInterface extends SpiInterfaceBase{
val spi = IO(new SSPIInterfaceIO)
val shiftMOSI = ShiftRegisters(spi.mosi, 3, false.B, true.B)
sck := spi.sck
csn := spi.csn
io.isEnR :=
(isSckPosedge & ~shiftCSn(1) & bitSel === 0.U & shiftMOSI(1) === 1.U & byteSel === 2.U ) |
(isSckPosedge & ~shiftCSn(1) & bitSel === 0.U & isSpiRead & byteSel >= 3.U )
when( shiftCSn(2) & ~shiftCSn(1) || (~shiftCSn(2) & shiftCSn(1)) ){ //CS下跳或上跳
spiCmd := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) & byteSel === 2.U & bitSel === 0.U ){ //CS为低且SCK上跳的第0byte
spiCmd := shiftMOSI(1)
}
spi.miso := exRego.extract(7)
when( shiftCSn(2) & ~shiftCSn(1) ){
bitSel := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
bitSel := bitSel + 1.U
}
//输入看SCK上升沿
when( isSckPosedge & ~shiftCSn(1) ){
when( bitSel === 0.U ){
exRegi := Cat( 0.U, shiftMOSI(1) )
}.otherwise{
exRegi := Cat( exRegi(6,0), shiftMOSI(1) )
}
}
//输出在SCK上升沿准备数据
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
exRego := 0.U //第一个byte 地址0
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
when( bitSel.andR ){
when((byteSel === 0.U || byteSel === 1.U) ){
exRego := 0.U //地址1cmd
} .elsewhen( isSpiRead ){
exRego := io.datar
}
}.otherwise{
exRego := exRego << 1
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrr := 0.U
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 0.U){ //CS为低且SCK上跳的第0byte
addrr := Cat( exRegi(6,0), shiftMOSI(1) )
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 1.U) {//CS为低且SCK上跳的第0byte
addrr := Cat(addrr(7,0), exRegi(6,0), shiftMOSI(1))
} .otherwise{ // byteSel > 1.U
when( isSckPosedge & byteSel >= 2.U & bitSel === 0.U ){
addrr := addrr + 1.U
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrw := 0.U
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 0.U){ //CS为低且SCK上跳的第0byte
addrw := Cat( exRegi(6,0), shiftMOSI(1) )
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 1.U) {//CS为低且SCK上跳的第0byte
addrw := Cat(addrw(7,0), exRegi(6,0), shiftMOSI(1) )
} .otherwise{ // byteSel > 1.U
when( isSckPosedgeNext(0) & byteSelNext >= 3.U & bitSelNext.andR ){
addrw := addrw + 1.U
}
}
}
class QSpiInterface(edge: Boolean) extends SpiInterfaceBase{
val qspi = IO(new QSPIInterfaceIO)
val shiftMOSI = ShiftRegisters(qspi.mosi, 3, 0.U(4.W), true.B)
sck := qspi.sck
csn := qspi.csn
qspi.miso := exRego(7, 4)
qspi.isDirIn := ~isSpiRead
io.isEnR :=
(isSckPosedge & ~shiftCSn(1) & bitSel === 0.U & shiftMOSI(1) === "b1000".U & byteSel === 2.U ) |
(isSckPosedge & ~shiftCSn(1) & bitSel === 0.U & isSpiRead & byteSel >= 3.U)
when( (shiftCSn(2) & ~shiftCSn(1)) || (~shiftCSn(2) & shiftCSn(1)) ){ //CS下跳或上跳
spiCmd := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) & byteSel === 2.U & bitSel === 0.U ){ //CS为低且SCK上跳的第0byte
spiCmd := shiftMOSI(1).extract(3)
}
when( shiftCSn(2) & ~shiftCSn(1) ){
bitSel := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
bitSel := ~bitSel
}
//输入看SCK上升沿
when( isSckPosedge & ~shiftCSn(1) ){
when( bitSel === 0.U ){
exRegi := Cat( 0.U, shiftMOSI(1) )
}.otherwise{
exRegi := Cat( exRegi(3,0), shiftMOSI(1) )
}
}
//输出在SCK XX沿准备数据
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
exRego := 0.U //第一个byte 地址0
} .elsewhen(
(if( edge ) {isSckPosedge} else {isSckNegedge})
& ~shiftCSn(1)
){
when( (if( edge ) { bitSel.andR } else { bitSel === 0.U }) ){
when( byteSel === 0.U || byteSel === 1.U || ( if( edge ) { false.B } else { byteSel === 2.U } ) ){
exRego := 0.U //地址1cmd
} .elsewhen( isSpiRead ){
exRego := io.datar
}
}.otherwise{
exRego := exRego << 4
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrr := 0.U
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 0.U){ //CS为低且SCK上跳的第0byte
addrr := Cat( exRegi(3,0), shiftMOSI(1) )
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 1.U) {//CS为低且SCK上跳的第0byte
addrr := Cat(addrr(7,0), exRegi(3,0), shiftMOSI(1))
} .otherwise{ // byteSel > 1.U
when( isSckPosedge & byteSel >= 2.U & bitSel === 0.U ){
addrr := addrr + 1.U
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrw := 0.U
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 0.U){ //CS为低且SCK上跳的第0byte
addrw := Cat( exRegi(3,0), shiftMOSI(1) )
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 1.U) {//CS为低且SCK上跳的第0byte
addrw := Cat(addrw(7,0), exRegi(3,0), shiftMOSI(1) )
} .otherwise{ // byteSel > 1.U
when( isSckPosedgeNext(0) & byteSelNext >= 3.U & bitSelNext.andR ){
addrw := addrw + 1.U
}
}
}
package BACK
import chisel3._
import chisel3.util._
class QSPIInterfaceIO extends Bundle{
val sck = Input(Bool())
val mosi = Input(UInt(4.W))
val miso = Output(UInt(4.W))
val isDirIn = Output(Bool())
val csn = Input(Bool())
}
class SSPIInterfaceIO extends Bundle{
val sck = Input(Bool())
val mosi = Input(Bool())
val miso = Output(Bool())
val csn = Input(Bool())
}
class RegAccessInterfaceIO extends Bundle{
val addrw = Output(UInt(16.W))
val addrr = Output(UInt(16.W))
val dataw = Output( UInt(8.W) )
val datar = Input( UInt(8.W) )
val isEnW = Output(Bool())
val isEnR = Output(Bool())
}
abstract class SpiInterfaceBase extends Module with RequireAsyncReset{
val io = IO(new RegAccessInterfaceIO)
val sck = Wire(Bool())
val csn = Wire(Bool())
//数据信号相对SCK的稳定应该由外部主机保证因此认为SCK采样时刻数据都是稳定正确的
val shiftSCK = ShiftRegisters(sck, 3, false.B, true.B)
val shiftCSn = ShiftRegisters(csn, 3, true.B, true.B)
val isSckPosedge = ~shiftSCK(2) & shiftSCK(1)
val isSckNegedge = shiftSCK(2) & ~shiftSCK(1)
val isSckPosedgeNext = ShiftRegisters(isSckPosedge, 2, false.B, true.B)
val exRego = RegInit(0.U(8.W))
val exRegi = RegInit(0.U(8.W))
val addrw = RegInit(0.U(16.W))
val addrr = RegInit(0.U(16.W))
val spiCmd = RegInit(0.U(1.W))
val isSpiWrite = spiCmd === 0.U
val isSpiRead = spiCmd === 1.U
val bitSel = RegInit(0.U(3.W))
val bitSelNext = RegNext(bitSel, 0.U(3.W))
val byteSel = RegInit(0.U(12.W))
val byteSelNext = RegNext(byteSel, 0.U(12.W))
io.isEnW := isSckPosedgeNext(0) & ~shiftCSn(2) & bitSelNext.andR & isSpiWrite & byteSelNext >= 3.U
io.dataw := exRegi
io.addrr := addrr
io.addrw := addrw
when( shiftCSn(2) & ~shiftCSn(1) ){
byteSel := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
when( bitSel.andR ){
byteSel := byteSel + 1.U
}
}
}
class SSpiInterface extends SpiInterfaceBase{
val spi = IO(new SSPIInterfaceIO)
val shiftMOSI = ShiftRegisters(spi.mosi, 3, false.B, true.B)
sck := spi.sck
csn := spi.csn
io.isEnR :=
(isSckPosedge & ~shiftCSn(1) & bitSel === 0.U & shiftMOSI(1) === 1.U & byteSel === 2.U ) |
(isSckPosedge & ~shiftCSn(1) & bitSel === 0.U & isSpiRead & byteSel >= 3.U )
when( shiftCSn(2) & ~shiftCSn(1) || (~shiftCSn(2) & shiftCSn(1)) ){ //CS下跳或上跳
spiCmd := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) & byteSel === 2.U & bitSel === 0.U ){ //CS为低且SCK上跳的第0byte
spiCmd := shiftMOSI(1)
}
spi.miso := exRego.extract(7)
when( shiftCSn(2) & ~shiftCSn(1) ){
bitSel := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
bitSel := bitSel + 1.U
}
//输入看SCK上升沿
when( isSckPosedge & ~shiftCSn(1) ){
when( bitSel === 0.U ){
exRegi := Cat( 0.U, shiftMOSI(1) )
}.otherwise{
exRegi := Cat( exRegi(6,0), shiftMOSI(1) )
}
}
//输出在SCK上升沿准备数据
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
exRego := 0.U //第一个byte 地址0
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
when( bitSel.andR ){
when((byteSel === 0.U || byteSel === 1.U) ){
exRego := 0.U //地址1cmd
} .elsewhen( isSpiRead ){
exRego := io.datar
}
}.otherwise{
exRego := exRego << 1
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrr := 0.U
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 0.U){ //CS为低且SCK上跳的第0byte
addrr := Cat( exRegi(6,0), shiftMOSI(1) )
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 1.U) {//CS为低且SCK上跳的第0byte
addrr := Cat(addrr(7,0), exRegi(6,0), shiftMOSI(1))
} .otherwise{ // byteSel > 1.U
when( isSckPosedge & byteSel >= 2.U & bitSel === 0.U ){
addrr := addrr + 1.U
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrw := 0.U
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 0.U){ //CS为低且SCK上跳的第0byte
addrw := Cat( exRegi(6,0), shiftMOSI(1) )
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 1.U) {//CS为低且SCK上跳的第0byte
addrw := Cat(addrw(7,0), exRegi(6,0), shiftMOSI(1) )
} .otherwise{ // byteSel > 1.U
when( isSckPosedgeNext(0) & byteSelNext >= 3.U & bitSelNext.andR ){
addrw := addrw + 1.U
}
}
}
class QSpiInterface(edge: Boolean) extends SpiInterfaceBase{
val qspi = IO(new QSPIInterfaceIO)
val shiftMOSI = ShiftRegisters(qspi.mosi, 3, 0.U(4.W), true.B)
sck := qspi.sck
csn := qspi.csn
qspi.miso := exRego(7, 4)
qspi.isDirIn := ~isSpiRead
io.isEnR :=
(isSckPosedge & ~shiftCSn(1) & bitSel === 0.U & shiftMOSI(1) === "b1000".U & byteSel === 2.U ) |
(isSckPosedge & ~shiftCSn(1) & bitSel === 0.U & isSpiRead & byteSel >= 3.U)
when( (shiftCSn(2) & ~shiftCSn(1)) || (~shiftCSn(2) & shiftCSn(1)) ){ //CS下跳或上跳
spiCmd := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) & byteSel === 2.U & bitSel === 0.U ){ //CS为低且SCK上跳的第0byte
spiCmd := shiftMOSI(1).extract(3)
}
when( shiftCSn(2) & ~shiftCSn(1) ){
bitSel := 0.U
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
bitSel := ~bitSel
}
//输入看SCK上升沿
when( isSckPosedge & ~shiftCSn(1) ){
when( bitSel === 0.U ){
exRegi := Cat( 0.U, shiftMOSI(1) )
}.otherwise{
exRegi := Cat( exRegi(3,0), shiftMOSI(1) )
}
}
//输出在SCK XX沿准备数据
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
exRego := 0.U //第一个byte 地址0
} .elsewhen(
(if( edge ) {isSckPosedge} else {isSckNegedge})
& ~shiftCSn(1)
){
when( (if( edge ) { bitSel.andR } else { bitSel === 0.U }) ){
when( byteSel === 0.U || byteSel === 1.U || ( if( edge ) { false.B } else { byteSel === 2.U } ) ){
exRego := 0.U //地址1cmd
} .elsewhen( isSpiRead ){
exRego := io.datar
}
}.otherwise{
exRego := exRego << 4
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrr := 0.U
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 0.U){ //CS为低且SCK上跳的第0byte
addrr := Cat( exRegi(3,0), shiftMOSI(1) )
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 1.U) {//CS为低且SCK上跳的第0byte
addrr := Cat(addrr(7,0), exRegi(3,0), shiftMOSI(1))
} .otherwise{ // byteSel > 1.U
when( isSckPosedge & byteSel >= 2.U & bitSel === 0.U ){
addrr := addrr + 1.U
}
}
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
addrw := 0.U
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 0.U){ //CS为低且SCK上跳的第0byte
addrw := Cat( exRegi(3,0), shiftMOSI(1) )
} .elsewhen(isSckPosedge & ~shiftCSn(1) & bitSel.andR & byteSel === 1.U) {//CS为低且SCK上跳的第0byte
addrw := Cat(addrw(7,0), exRegi(3,0), shiftMOSI(1) )
} .otherwise{ // byteSel > 1.U
when( isSckPosedgeNext(0) & byteSelNext >= 3.U & bitSelNext.andR ){
addrw := addrw + 1.U
}
}
}

View File

@@ -1,78 +1,78 @@
package BACK
import chisel3._
import chisel3.util._
object b4b5Encoder{
def apply( enq: UInt ): UInt = {
Mux1H(Seq(
(enq === "b0000".U) -> "b11110".U(5.W),
(enq === "b0001".U) -> "b01001".U(5.W),
(enq === "b0010".U) -> "b10100".U(5.W),
(enq === "b0011".U) -> "b10101".U(5.W),
(enq === "b0100".U) -> "b01010".U(5.W),
(enq === "b0101".U) -> "b01011".U(5.W),
(enq === "b0110".U) -> "b01110".U(5.W),
(enq === "b0111".U) -> "b01111".U(5.W),
(enq === "b1000".U) -> "b10010".U(5.W),
(enq === "b1001".U) -> "b10011".U(5.W),
(enq === "b1010".U) -> "b10110".U(5.W),
(enq === "b1011".U) -> "b10111".U(5.W),
(enq === "b1100".U) -> "b11010".U(5.W),
(enq === "b1101".U) -> "b11011".U(5.W),
(enq === "b1110".U) -> "b11100".U(5.W),
(enq === "b1111".U) -> "b11101".U(5.W),
))
}
}
object b4b5Decoder{
def apply( enq: UInt ): UInt = {
Mux1H(Seq(
(enq === "b11110".U) -> "b0000".U(4.W),
(enq === "b01001".U) -> "b0001".U(4.W),
(enq === "b10100".U) -> "b0010".U(4.W),
(enq === "b10101".U) -> "b0011".U(4.W),
(enq === "b01010".U) -> "b0100".U(4.W),
(enq === "b01011".U) -> "b0101".U(4.W),
(enq === "b01110".U) -> "b0110".U(4.W),
(enq === "b01111".U) -> "b0111".U(4.W),
(enq === "b10010".U) -> "b1000".U(4.W),
(enq === "b10011".U) -> "b1001".U(4.W),
(enq === "b10110".U) -> "b1010".U(4.W),
(enq === "b10111".U) -> "b1011".U(4.W),
(enq === "b11010".U) -> "b1100".U(4.W),
(enq === "b11011".U) -> "b1101".U(4.W),
(enq === "b11100".U) -> "b1110".U(4.W),
(enq === "b11101".U) -> "b1111".U(4.W),
))
}
}
object Dualb4b5Encoder{
def apply( enq: UInt ): UInt = {
require( enq.getWidth == 8, "Require Failed @ Dualb4b5Encoder!" )
Cat( b4b5Encoder(enq(7,4)), b4b5Encoder(enq(3,0)) )
}
}
object Dualb4b5Decoder{
def apply( enq: UInt ): UInt = {
require( enq.getWidth == 10, "Require Failed @ Dualb4b5Decoder!" )
Cat( b4b5Decoder(enq(9,5)), b4b5Decoder(enq(4,0)) )
}
}
class b4b5DualEncode extends Module with RequireAsyncReset{
val io = IO(new Encode_Bundle)
io.dataOut := Dualb4b5Encoder(io.dataIn)
}
class b4b5DualDecode extends Module with RequireAsyncReset{
val io = IO(new Decode_Bundle)
io.dataOut := Dualb4b5Decoder(io.dataIn)
}
package BACK
import chisel3._
import chisel3.util._
object b4b5Encoder{
def apply( enq: UInt ): UInt = {
Mux1H(Seq(
(enq === "b0000".U) -> "b11110".U(5.W),
(enq === "b0001".U) -> "b01001".U(5.W),
(enq === "b0010".U) -> "b10100".U(5.W),
(enq === "b0011".U) -> "b10101".U(5.W),
(enq === "b0100".U) -> "b01010".U(5.W),
(enq === "b0101".U) -> "b01011".U(5.W),
(enq === "b0110".U) -> "b01110".U(5.W),
(enq === "b0111".U) -> "b01111".U(5.W),
(enq === "b1000".U) -> "b10010".U(5.W),
(enq === "b1001".U) -> "b10011".U(5.W),
(enq === "b1010".U) -> "b10110".U(5.W),
(enq === "b1011".U) -> "b10111".U(5.W),
(enq === "b1100".U) -> "b11010".U(5.W),
(enq === "b1101".U) -> "b11011".U(5.W),
(enq === "b1110".U) -> "b11100".U(5.W),
(enq === "b1111".U) -> "b11101".U(5.W),
))
}
}
object b4b5Decoder{
def apply( enq: UInt ): UInt = {
Mux1H(Seq(
(enq === "b11110".U) -> "b0000".U(4.W),
(enq === "b01001".U) -> "b0001".U(4.W),
(enq === "b10100".U) -> "b0010".U(4.W),
(enq === "b10101".U) -> "b0011".U(4.W),
(enq === "b01010".U) -> "b0100".U(4.W),
(enq === "b01011".U) -> "b0101".U(4.W),
(enq === "b01110".U) -> "b0110".U(4.W),
(enq === "b01111".U) -> "b0111".U(4.W),
(enq === "b10010".U) -> "b1000".U(4.W),
(enq === "b10011".U) -> "b1001".U(4.W),
(enq === "b10110".U) -> "b1010".U(4.W),
(enq === "b10111".U) -> "b1011".U(4.W),
(enq === "b11010".U) -> "b1100".U(4.W),
(enq === "b11011".U) -> "b1101".U(4.W),
(enq === "b11100".U) -> "b1110".U(4.W),
(enq === "b11101".U) -> "b1111".U(4.W),
))
}
}
object Dualb4b5Encoder{
def apply( enq: UInt ): UInt = {
require( enq.getWidth == 8, "Require Failed @ Dualb4b5Encoder!" )
Cat( b4b5Encoder(enq(7,4)), b4b5Encoder(enq(3,0)) )
}
}
object Dualb4b5Decoder{
def apply( enq: UInt ): UInt = {
require( enq.getWidth == 10, "Require Failed @ Dualb4b5Decoder!" )
Cat( b4b5Decoder(enq(9,5)), b4b5Decoder(enq(4,0)) )
}
}
class b4b5DualEncode extends Module with RequireAsyncReset{
val io = IO(new Encode_Bundle)
io.dataOut := Dualb4b5Encoder(io.dataIn)
}
class b4b5DualDecode extends Module with RequireAsyncReset{
val io = IO(new Decode_Bundle)
io.dataOut := Dualb4b5Decoder(io.dataIn)
}

View File

@@ -1,192 +1,192 @@
package BACK
import chisel3._
import chisel3.util._
class Encode_Bundle extends Bundle{
val dataIn = Input(UInt(8.W))
val isEnable = Input(Bool())
val dataOut = Output(UInt(10.W))
}
class Decode_Bundle extends Bundle{
val dataIn = Input(UInt(10.W))
val dataOut = Output(UInt(8.W))
}
class b8b10Encode extends Module with RequireAsyncReset{
val io = IO(new Encode_Bundle)
val rdTest = IO(Output(Bool())) //测试使用
dontTouch(rdTest)
val rd = RegInit(false.B); rdTest := rd
val b5b6LookUp = Mux1H(Seq(
(io.dataIn(4,0) === "b00000".U) -> Mux( ~rd, "b100111".U(6.W), "b011000".U(6.W) ),
(io.dataIn(4,0) === "b00001".U) -> Mux( ~rd, "b011101".U(6.W), "b100010".U(6.W) ),
(io.dataIn(4,0) === "b00010".U) -> Mux( ~rd, "b101101".U(6.W), "b010010".U(6.W) ),
(io.dataIn(4,0) === "b00011".U) -> "b110001".U(6.W),
(io.dataIn(4,0) === "b00100".U) -> Mux( ~rd, "b110101".U(6.W), "b001010".U(6.W) ),
(io.dataIn(4,0) === "b00101".U) -> "b101001".U(6.W),
(io.dataIn(4,0) === "b00110".U) -> "b011001".U(6.W),
(io.dataIn(4,0) === "b00111".U) -> Mux( ~rd, "b111000".U(6.W), "b000111".U(6.W) ),
(io.dataIn(4,0) === "b01000".U) -> Mux( ~rd, "b111001".U(6.W), "b000110".U(6.W) ),
(io.dataIn(4,0) === "b01001".U) -> "b100101".U(6.W),
(io.dataIn(4,0) === "b01010".U) -> "b010101".U(6.W),
(io.dataIn(4,0) === "b01011".U) -> "b110100".U(6.W),
(io.dataIn(4,0) === "b01100".U) -> "b001101".U(6.W),
(io.dataIn(4,0) === "b01101".U) -> "b101100".U(6.W),
(io.dataIn(4,0) === "b01110".U) -> "b011100".U(6.W),
(io.dataIn(4,0) === "b01111".U) -> Mux( ~rd, "b010111".U(6.W), "b101000".U(6.W) ),
(io.dataIn(4,0) === "b10000".U) -> Mux( ~rd, "b011011".U(6.W), "b100100".U(6.W) ),
(io.dataIn(4,0) === "b10001".U) -> "b100011".U(6.W),
(io.dataIn(4,0) === "b10010".U) -> "b010011".U(6.W),
(io.dataIn(4,0) === "b10011".U) -> "b110010".U(6.W),
(io.dataIn(4,0) === "b10100".U) -> "b001011".U(6.W),
(io.dataIn(4,0) === "b10101".U) -> "b101010".U(6.W),
(io.dataIn(4,0) === "b10110".U) -> "b011010".U(6.W),
(io.dataIn(4,0) === "b10111".U) -> Mux( ~rd, "b111010".U(6.W), "b000101".U(6.W) ),
(io.dataIn(4,0) === "b11000".U) -> Mux( ~rd, "b110011".U(6.W), "b001100".U(6.W) ),
(io.dataIn(4,0) === "b11001".U) -> "b100110".U(6.W),
(io.dataIn(4,0) === "b11010".U) -> "b010110".U(6.W),
(io.dataIn(4,0) === "b11011".U) -> Mux( ~rd, "b110110".U(6.W), "b001001".U(6.W) ),
(io.dataIn(4,0) === "b11100".U) -> "b001110".U(6.W),
(io.dataIn(4,0) === "b11101".U) -> Mux( ~rd, "b101110".U(6.W), "b010001".U(6.W) ),
(io.dataIn(4,0) === "b11110".U) -> Mux( ~rd, "b011110".U(6.W), "b100001".U(6.W) ),
(io.dataIn(4,0) === "b11111".U) -> Mux( ~rd, "b101011".U(6.W), "b010100".U(6.W) )
))
val b5b6RD = Mux1H(Seq(
(io.dataIn(4,0) === "b00000".U) -> ~rd,
(io.dataIn(4,0) === "b00001".U) -> ~rd,
(io.dataIn(4,0) === "b00010".U) -> ~rd,
(io.dataIn(4,0) === "b00011".U) -> rd,
(io.dataIn(4,0) === "b00100".U) -> ~rd,
(io.dataIn(4,0) === "b00101".U) -> rd,
(io.dataIn(4,0) === "b00110".U) -> rd,
(io.dataIn(4,0) === "b00111".U) -> rd,
(io.dataIn(4,0) === "b01000".U) -> ~rd,
(io.dataIn(4,0) === "b01001".U) -> rd,
(io.dataIn(4,0) === "b01010".U) -> rd,
(io.dataIn(4,0) === "b01011".U) -> rd,
(io.dataIn(4,0) === "b01100".U) -> rd,
(io.dataIn(4,0) === "b01101".U) -> rd,
(io.dataIn(4,0) === "b01110".U) -> rd,
(io.dataIn(4,0) === "b01111".U) -> ~rd,
(io.dataIn(4,0) === "b10000".U) -> ~rd,
(io.dataIn(4,0) === "b10001".U) -> rd,
(io.dataIn(4,0) === "b10010".U) -> rd,
(io.dataIn(4,0) === "b10011".U) -> rd,
(io.dataIn(4,0) === "b10100".U) -> rd,
(io.dataIn(4,0) === "b10101".U) -> rd,
(io.dataIn(4,0) === "b10110".U) -> rd,
(io.dataIn(4,0) === "b10111".U) -> ~rd,
(io.dataIn(4,0) === "b11000".U) -> ~rd,
(io.dataIn(4,0) === "b11001".U) -> rd,
(io.dataIn(4,0) === "b11010".U) -> rd,
(io.dataIn(4,0) === "b11011".U) -> ~rd,
(io.dataIn(4,0) === "b11100".U) -> rd,
(io.dataIn(4,0) === "b11101".U) -> ~rd,
(io.dataIn(4,0) === "b11110".U) -> ~rd,
(io.dataIn(4,0) === "b11111".U) -> ~rd,
))
val b3b4LookUp = Mux1H(Seq(
(io.dataIn(7,5) === "b000".U) -> Mux( ~b5b6RD, "b1011".U(4.W), "b0100".U(4.W) ),
(io.dataIn(7,5) === "b001".U) -> "b1001".U(4.W),
(io.dataIn(7,5) === "b010".U) -> "b0101".U(4.W),
(io.dataIn(7,5) === "b011".U) -> Mux( ~b5b6RD, "b1100".U(4.W), "b0011".U(4.W) ),
(io.dataIn(7,5) === "b100".U) -> Mux( ~b5b6RD, "b1101".U(4.W), "b0010".U(4.W) ),
(io.dataIn(7,5) === "b101".U) -> "b1010".U(4.W),
(io.dataIn(7,5) === "b110".U) -> "b0110".U(4.W),
(io.dataIn(7,5) === "b111".U) -> MuxCase( Mux( ~b5b6RD, "b1110".U(4.W), "b0001".U(4.W) ), Array(
((io.dataIn(4,0) === 17.U || io.dataIn(4,0) === 18.U || io.dataIn(4,0) === 20.U) & ~b5b6RD) -> "b0111".U(4.W), // 17, 18, 20 are special cases
((io.dataIn(4,0) === 11.U || io.dataIn(4,0) === 13.U || io.dataIn(4,0) === 14.U) & b5b6RD) -> "b1000".U(4.W), // 11, 13, 14 are special cases
))
))
val b3b4RD = Mux1H(Seq(
(io.dataIn(7,5) === "b000".U) -> ~b5b6RD,
(io.dataIn(7,5) === "b001".U) -> b5b6RD,
(io.dataIn(7,5) === "b010".U) -> b5b6RD,
(io.dataIn(7,5) === "b011".U) -> b5b6RD,
(io.dataIn(7,5) === "b100".U) -> ~b5b6RD,
(io.dataIn(7,5) === "b101".U) -> b5b6RD,
(io.dataIn(7,5) === "b110".U) -> b5b6RD,
(io.dataIn(7,5) === "b111".U) -> ~b5b6RD,
))
io.dataOut := Cat(b5b6LookUp, b3b4LookUp)
when (io.isEnable) {
rd := b3b4RD
assert( io.dataOut(4,0) =/= 0.U && io.dataOut(4,0) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(5,1) =/= 0.U && io.dataOut(5,1) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(6,2) =/= 0.U && io.dataOut(6,2) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(7,3) =/= 0.U && io.dataOut(7,3) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(8,4) =/= 0.U && io.dataOut(8,4) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(9,5) =/= 0.U && io.dataOut(9,5) =/= 31.U, "Invalid 8b10b encoding Output!")
}
}
class b8b10Decode extends Module with RequireAsyncReset{
val io = IO(new Decode_Bundle)
val b5b6LookUp = Mux1H(Seq(
(io.dataIn(9,4) === "b100111".U(6.W) || io.dataIn(9,4) === "b011000".U(6.W) ) -> "b00000".U,
(io.dataIn(9,4) === "b011101".U(6.W) || io.dataIn(9,4) === "b100010".U(6.W) ) -> "b00001".U,
(io.dataIn(9,4) === "b101101".U(6.W) || io.dataIn(9,4) === "b010010".U(6.W) ) -> "b00010".U,
(io.dataIn(9,4) === "b110001".U(6.W)) -> "b00011".U,
(io.dataIn(9,4) === "b110101".U(6.W) || io.dataIn(9,4) === "b001010".U(6.W) ) -> "b00100".U,
(io.dataIn(9,4) === "b101001".U(6.W)) -> "b00101".U,
(io.dataIn(9,4) === "b011001".U(6.W)) -> "b00110".U,
(io.dataIn(9,4) === "b111000".U(6.W) || io.dataIn(9,4) === "b000111".U(6.W) ) -> "b00111".U,
(io.dataIn(9,4) === "b111001".U(6.W) || io.dataIn(9,4) === "b000110".U(6.W) ) -> "b01000".U,
(io.dataIn(9,4) === "b100101".U(6.W)) -> "b01001".U,
(io.dataIn(9,4) === "b010101".U(6.W)) -> "b01010".U,
(io.dataIn(9,4) === "b110100".U(6.W)) -> "b01011".U,
(io.dataIn(9,4) === "b001101".U(6.W)) -> "b01100".U,
(io.dataIn(9,4) === "b101100".U(6.W)) -> "b01101".U,
(io.dataIn(9,4) === "b011100".U(6.W)) -> "b01110".U,
(io.dataIn(9,4) === "b010111".U(6.W) || io.dataIn(9,4) === "b101000".U(6.W) ) -> "b01111".U,
(io.dataIn(9,4) === "b011011".U(6.W) || io.dataIn(9,4) === "b100100".U(6.W) ) -> "b10000".U,
(io.dataIn(9,4) === "b100011".U(6.W)) -> "b10001".U,
(io.dataIn(9,4) === "b010011".U(6.W)) -> "b10010".U,
(io.dataIn(9,4) === "b110010".U(6.W)) -> "b10011".U,
(io.dataIn(9,4) === "b001011".U(6.W)) -> "b10100".U,
(io.dataIn(9,4) === "b101010".U(6.W)) -> "b10101".U,
(io.dataIn(9,4) === "b011010".U(6.W)) -> "b10110".U,
(io.dataIn(9,4) === "b111010".U(6.W) || io.dataIn(9,4) === "b000101".U(6.W) ) -> "b10111".U,
(io.dataIn(9,4) === "b110011".U(6.W) || io.dataIn(9,4) === "b001100".U(6.W) ) -> "b11000".U,
(io.dataIn(9,4) === "b100110".U(6.W)) -> "b11001".U,
(io.dataIn(9,4) === "b010110".U(6.W)) -> "b11010".U,
(io.dataIn(9,4) === "b110110".U(6.W) || io.dataIn(9,4) === "b001001".U(6.W) ) -> "b11011".U,
(io.dataIn(9,4) === "b001110".U(6.W)) -> "b11100".U,
(io.dataIn(9,4) === "b101110".U(6.W) || io.dataIn(9,4) === "b010001".U(6.W) ) -> "b11101".U,
(io.dataIn(9,4) === "b011110".U(6.W) || io.dataIn(9,4) === "b100001".U(6.W) ) -> "b11110".U,
(io.dataIn(9,4) === "b101011".U(6.W) || io.dataIn(9,4) === "b010100".U(6.W) ) -> "b11111".U,
))
val b3b4LookUp = Mux1H(Seq(
(io.dataIn(3,0) === "b1011".U(4.W) || io.dataIn(3,0) === "b0100".U(4.W) ) -> "b000".U,
(io.dataIn(3,0) === "b1001".U(4.W)) -> "b001".U,
(io.dataIn(3,0) === "b0101".U(4.W)) -> "b010".U,
(io.dataIn(3,0) === "b1100".U(4.W) || io.dataIn(3,0) === "b0011".U(4.W) ) -> "b011".U,
(io.dataIn(3,0) === "b1101".U(4.W) || io.dataIn(3,0) === "b0010".U(4.W) ) -> "b100".U,
(io.dataIn(3,0) === "b1010".U(4.W)) -> "b101".U,
(io.dataIn(3,0) === "b0110".U(4.W)) -> "b110".U,
(io.dataIn(3,0) === "b1110".U(4.W) ||
io.dataIn(3,0) === "b0001".U(4.W) ||
io.dataIn(3,0) === "b0111".U(4.W) ||
io.dataIn(3,0) === "b1000".U(4.W)) -> "b111".U,
))
io.dataOut := Cat(b3b4LookUp, b5b6LookUp)
}
package BACK
import chisel3._
import chisel3.util._
class Encode_Bundle extends Bundle{
val dataIn = Input(UInt(8.W))
val isEnable = Input(Bool())
val dataOut = Output(UInt(10.W))
}
class Decode_Bundle extends Bundle{
val dataIn = Input(UInt(10.W))
val dataOut = Output(UInt(8.W))
}
class b8b10Encode extends Module with RequireAsyncReset{
val io = IO(new Encode_Bundle)
val rdTest = IO(Output(Bool())) //测试使用
dontTouch(rdTest)
val rd = RegInit(false.B); rdTest := rd
val b5b6LookUp = Mux1H(Seq(
(io.dataIn(4,0) === "b00000".U) -> Mux( ~rd, "b100111".U(6.W), "b011000".U(6.W) ),
(io.dataIn(4,0) === "b00001".U) -> Mux( ~rd, "b011101".U(6.W), "b100010".U(6.W) ),
(io.dataIn(4,0) === "b00010".U) -> Mux( ~rd, "b101101".U(6.W), "b010010".U(6.W) ),
(io.dataIn(4,0) === "b00011".U) -> "b110001".U(6.W),
(io.dataIn(4,0) === "b00100".U) -> Mux( ~rd, "b110101".U(6.W), "b001010".U(6.W) ),
(io.dataIn(4,0) === "b00101".U) -> "b101001".U(6.W),
(io.dataIn(4,0) === "b00110".U) -> "b011001".U(6.W),
(io.dataIn(4,0) === "b00111".U) -> Mux( ~rd, "b111000".U(6.W), "b000111".U(6.W) ),
(io.dataIn(4,0) === "b01000".U) -> Mux( ~rd, "b111001".U(6.W), "b000110".U(6.W) ),
(io.dataIn(4,0) === "b01001".U) -> "b100101".U(6.W),
(io.dataIn(4,0) === "b01010".U) -> "b010101".U(6.W),
(io.dataIn(4,0) === "b01011".U) -> "b110100".U(6.W),
(io.dataIn(4,0) === "b01100".U) -> "b001101".U(6.W),
(io.dataIn(4,0) === "b01101".U) -> "b101100".U(6.W),
(io.dataIn(4,0) === "b01110".U) -> "b011100".U(6.W),
(io.dataIn(4,0) === "b01111".U) -> Mux( ~rd, "b010111".U(6.W), "b101000".U(6.W) ),
(io.dataIn(4,0) === "b10000".U) -> Mux( ~rd, "b011011".U(6.W), "b100100".U(6.W) ),
(io.dataIn(4,0) === "b10001".U) -> "b100011".U(6.W),
(io.dataIn(4,0) === "b10010".U) -> "b010011".U(6.W),
(io.dataIn(4,0) === "b10011".U) -> "b110010".U(6.W),
(io.dataIn(4,0) === "b10100".U) -> "b001011".U(6.W),
(io.dataIn(4,0) === "b10101".U) -> "b101010".U(6.W),
(io.dataIn(4,0) === "b10110".U) -> "b011010".U(6.W),
(io.dataIn(4,0) === "b10111".U) -> Mux( ~rd, "b111010".U(6.W), "b000101".U(6.W) ),
(io.dataIn(4,0) === "b11000".U) -> Mux( ~rd, "b110011".U(6.W), "b001100".U(6.W) ),
(io.dataIn(4,0) === "b11001".U) -> "b100110".U(6.W),
(io.dataIn(4,0) === "b11010".U) -> "b010110".U(6.W),
(io.dataIn(4,0) === "b11011".U) -> Mux( ~rd, "b110110".U(6.W), "b001001".U(6.W) ),
(io.dataIn(4,0) === "b11100".U) -> "b001110".U(6.W),
(io.dataIn(4,0) === "b11101".U) -> Mux( ~rd, "b101110".U(6.W), "b010001".U(6.W) ),
(io.dataIn(4,0) === "b11110".U) -> Mux( ~rd, "b011110".U(6.W), "b100001".U(6.W) ),
(io.dataIn(4,0) === "b11111".U) -> Mux( ~rd, "b101011".U(6.W), "b010100".U(6.W) )
))
val b5b6RD = Mux1H(Seq(
(io.dataIn(4,0) === "b00000".U) -> ~rd,
(io.dataIn(4,0) === "b00001".U) -> ~rd,
(io.dataIn(4,0) === "b00010".U) -> ~rd,
(io.dataIn(4,0) === "b00011".U) -> rd,
(io.dataIn(4,0) === "b00100".U) -> ~rd,
(io.dataIn(4,0) === "b00101".U) -> rd,
(io.dataIn(4,0) === "b00110".U) -> rd,
(io.dataIn(4,0) === "b00111".U) -> rd,
(io.dataIn(4,0) === "b01000".U) -> ~rd,
(io.dataIn(4,0) === "b01001".U) -> rd,
(io.dataIn(4,0) === "b01010".U) -> rd,
(io.dataIn(4,0) === "b01011".U) -> rd,
(io.dataIn(4,0) === "b01100".U) -> rd,
(io.dataIn(4,0) === "b01101".U) -> rd,
(io.dataIn(4,0) === "b01110".U) -> rd,
(io.dataIn(4,0) === "b01111".U) -> ~rd,
(io.dataIn(4,0) === "b10000".U) -> ~rd,
(io.dataIn(4,0) === "b10001".U) -> rd,
(io.dataIn(4,0) === "b10010".U) -> rd,
(io.dataIn(4,0) === "b10011".U) -> rd,
(io.dataIn(4,0) === "b10100".U) -> rd,
(io.dataIn(4,0) === "b10101".U) -> rd,
(io.dataIn(4,0) === "b10110".U) -> rd,
(io.dataIn(4,0) === "b10111".U) -> ~rd,
(io.dataIn(4,0) === "b11000".U) -> ~rd,
(io.dataIn(4,0) === "b11001".U) -> rd,
(io.dataIn(4,0) === "b11010".U) -> rd,
(io.dataIn(4,0) === "b11011".U) -> ~rd,
(io.dataIn(4,0) === "b11100".U) -> rd,
(io.dataIn(4,0) === "b11101".U) -> ~rd,
(io.dataIn(4,0) === "b11110".U) -> ~rd,
(io.dataIn(4,0) === "b11111".U) -> ~rd,
))
val b3b4LookUp = Mux1H(Seq(
(io.dataIn(7,5) === "b000".U) -> Mux( ~b5b6RD, "b1011".U(4.W), "b0100".U(4.W) ),
(io.dataIn(7,5) === "b001".U) -> "b1001".U(4.W),
(io.dataIn(7,5) === "b010".U) -> "b0101".U(4.W),
(io.dataIn(7,5) === "b011".U) -> Mux( ~b5b6RD, "b1100".U(4.W), "b0011".U(4.W) ),
(io.dataIn(7,5) === "b100".U) -> Mux( ~b5b6RD, "b1101".U(4.W), "b0010".U(4.W) ),
(io.dataIn(7,5) === "b101".U) -> "b1010".U(4.W),
(io.dataIn(7,5) === "b110".U) -> "b0110".U(4.W),
(io.dataIn(7,5) === "b111".U) -> MuxCase( Mux( ~b5b6RD, "b1110".U(4.W), "b0001".U(4.W) ), Array(
((io.dataIn(4,0) === 17.U || io.dataIn(4,0) === 18.U || io.dataIn(4,0) === 20.U) & ~b5b6RD) -> "b0111".U(4.W), // 17, 18, 20 are special cases
((io.dataIn(4,0) === 11.U || io.dataIn(4,0) === 13.U || io.dataIn(4,0) === 14.U) & b5b6RD) -> "b1000".U(4.W), // 11, 13, 14 are special cases
))
))
val b3b4RD = Mux1H(Seq(
(io.dataIn(7,5) === "b000".U) -> ~b5b6RD,
(io.dataIn(7,5) === "b001".U) -> b5b6RD,
(io.dataIn(7,5) === "b010".U) -> b5b6RD,
(io.dataIn(7,5) === "b011".U) -> b5b6RD,
(io.dataIn(7,5) === "b100".U) -> ~b5b6RD,
(io.dataIn(7,5) === "b101".U) -> b5b6RD,
(io.dataIn(7,5) === "b110".U) -> b5b6RD,
(io.dataIn(7,5) === "b111".U) -> ~b5b6RD,
))
io.dataOut := Cat(b5b6LookUp, b3b4LookUp)
when (io.isEnable) {
rd := b3b4RD
assert( io.dataOut(4,0) =/= 0.U && io.dataOut(4,0) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(5,1) =/= 0.U && io.dataOut(5,1) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(6,2) =/= 0.U && io.dataOut(6,2) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(7,3) =/= 0.U && io.dataOut(7,3) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(8,4) =/= 0.U && io.dataOut(8,4) =/= 31.U, "Invalid 8b10b encoding Output!")
assert( io.dataOut(9,5) =/= 0.U && io.dataOut(9,5) =/= 31.U, "Invalid 8b10b encoding Output!")
}
}
class b8b10Decode extends Module with RequireAsyncReset{
val io = IO(new Decode_Bundle)
val b5b6LookUp = Mux1H(Seq(
(io.dataIn(9,4) === "b100111".U(6.W) || io.dataIn(9,4) === "b011000".U(6.W) ) -> "b00000".U,
(io.dataIn(9,4) === "b011101".U(6.W) || io.dataIn(9,4) === "b100010".U(6.W) ) -> "b00001".U,
(io.dataIn(9,4) === "b101101".U(6.W) || io.dataIn(9,4) === "b010010".U(6.W) ) -> "b00010".U,
(io.dataIn(9,4) === "b110001".U(6.W)) -> "b00011".U,
(io.dataIn(9,4) === "b110101".U(6.W) || io.dataIn(9,4) === "b001010".U(6.W) ) -> "b00100".U,
(io.dataIn(9,4) === "b101001".U(6.W)) -> "b00101".U,
(io.dataIn(9,4) === "b011001".U(6.W)) -> "b00110".U,
(io.dataIn(9,4) === "b111000".U(6.W) || io.dataIn(9,4) === "b000111".U(6.W) ) -> "b00111".U,
(io.dataIn(9,4) === "b111001".U(6.W) || io.dataIn(9,4) === "b000110".U(6.W) ) -> "b01000".U,
(io.dataIn(9,4) === "b100101".U(6.W)) -> "b01001".U,
(io.dataIn(9,4) === "b010101".U(6.W)) -> "b01010".U,
(io.dataIn(9,4) === "b110100".U(6.W)) -> "b01011".U,
(io.dataIn(9,4) === "b001101".U(6.W)) -> "b01100".U,
(io.dataIn(9,4) === "b101100".U(6.W)) -> "b01101".U,
(io.dataIn(9,4) === "b011100".U(6.W)) -> "b01110".U,
(io.dataIn(9,4) === "b010111".U(6.W) || io.dataIn(9,4) === "b101000".U(6.W) ) -> "b01111".U,
(io.dataIn(9,4) === "b011011".U(6.W) || io.dataIn(9,4) === "b100100".U(6.W) ) -> "b10000".U,
(io.dataIn(9,4) === "b100011".U(6.W)) -> "b10001".U,
(io.dataIn(9,4) === "b010011".U(6.W)) -> "b10010".U,
(io.dataIn(9,4) === "b110010".U(6.W)) -> "b10011".U,
(io.dataIn(9,4) === "b001011".U(6.W)) -> "b10100".U,
(io.dataIn(9,4) === "b101010".U(6.W)) -> "b10101".U,
(io.dataIn(9,4) === "b011010".U(6.W)) -> "b10110".U,
(io.dataIn(9,4) === "b111010".U(6.W) || io.dataIn(9,4) === "b000101".U(6.W) ) -> "b10111".U,
(io.dataIn(9,4) === "b110011".U(6.W) || io.dataIn(9,4) === "b001100".U(6.W) ) -> "b11000".U,
(io.dataIn(9,4) === "b100110".U(6.W)) -> "b11001".U,
(io.dataIn(9,4) === "b010110".U(6.W)) -> "b11010".U,
(io.dataIn(9,4) === "b110110".U(6.W) || io.dataIn(9,4) === "b001001".U(6.W) ) -> "b11011".U,
(io.dataIn(9,4) === "b001110".U(6.W)) -> "b11100".U,
(io.dataIn(9,4) === "b101110".U(6.W) || io.dataIn(9,4) === "b010001".U(6.W) ) -> "b11101".U,
(io.dataIn(9,4) === "b011110".U(6.W) || io.dataIn(9,4) === "b100001".U(6.W) ) -> "b11110".U,
(io.dataIn(9,4) === "b101011".U(6.W) || io.dataIn(9,4) === "b010100".U(6.W) ) -> "b11111".U,
))
val b3b4LookUp = Mux1H(Seq(
(io.dataIn(3,0) === "b1011".U(4.W) || io.dataIn(3,0) === "b0100".U(4.W) ) -> "b000".U,
(io.dataIn(3,0) === "b1001".U(4.W)) -> "b001".U,
(io.dataIn(3,0) === "b0101".U(4.W)) -> "b010".U,
(io.dataIn(3,0) === "b1100".U(4.W) || io.dataIn(3,0) === "b0011".U(4.W) ) -> "b011".U,
(io.dataIn(3,0) === "b1101".U(4.W) || io.dataIn(3,0) === "b0010".U(4.W) ) -> "b100".U,
(io.dataIn(3,0) === "b1010".U(4.W)) -> "b101".U,
(io.dataIn(3,0) === "b0110".U(4.W)) -> "b110".U,
(io.dataIn(3,0) === "b1110".U(4.W) ||
io.dataIn(3,0) === "b0001".U(4.W) ||
io.dataIn(3,0) === "b0111".U(4.W) ||
io.dataIn(3,0) === "b1000".U(4.W)) -> "b111".U,
))
io.dataOut := Cat(b3b4LookUp, b5b6LookUp)
}

View File

@@ -1,87 +1,87 @@
package BACK
import chisel3._
import chisel3.util._
//-----------------------------------------------------------------------------
// 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[7: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;
//-----------------------------------------------------------------------------
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 )
// 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 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))
dataIn := Cat(io.dataIn.asBools)
lfsr_c( 0) := lfsr_q(24) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(6)
lfsr_c( 1) := lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(0) ^ dataIn(1) ^ dataIn(6) ^ dataIn(7)
lfsr_c( 2) := lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(0) ^ dataIn(1) ^ dataIn(2) ^ dataIn(6) ^ dataIn(7)
lfsr_c( 3) := lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(2) ^ dataIn(3) ^ dataIn(7)
lfsr_c( 4) := lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(2) ^ dataIn(3) ^ dataIn(4) ^ dataIn(6)
lfsr_c( 5) := lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(0) ^ dataIn(1) ^ dataIn(3) ^ dataIn(4) ^ dataIn(5) ^ dataIn(6) ^ dataIn(7)
lfsr_c( 6) := lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(2) ^ dataIn(4) ^ dataIn(5) ^ dataIn(6) ^ dataIn(7)
lfsr_c( 7) := lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(31) ^ dataIn(0) ^ dataIn(2) ^ dataIn(3) ^ dataIn(5) ^ dataIn(7)
lfsr_c( 8) := lfsr_q( 0) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(28) ^ dataIn(0) ^ dataIn(1) ^ dataIn(3) ^ dataIn(4)
lfsr_c( 9) := lfsr_q( 1) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ dataIn(1) ^ dataIn(2) ^ dataIn(4) ^ dataIn(5)
lfsr_c(10) := lfsr_q( 2) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ dataIn(0) ^ dataIn(2) ^ dataIn(3) ^ dataIn(5)
lfsr_c(11) := lfsr_q( 3) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(28) ^ dataIn(0) ^ dataIn(1) ^ dataIn(3) ^ dataIn(4)
lfsr_c(12) := lfsr_q( 4) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(1) ^ dataIn(2) ^ dataIn(4) ^ dataIn(5) ^ dataIn(6)
lfsr_c(13) := lfsr_q( 5) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(2) ^ dataIn(3) ^ dataIn(5) ^ dataIn(6) ^ dataIn(7)
lfsr_c(14) := lfsr_q( 6) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(2) ^ dataIn(3) ^ dataIn(4) ^ dataIn(6) ^ dataIn(7)
lfsr_c(15) := lfsr_q( 7) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ dataIn(3) ^ dataIn(4) ^ dataIn(5) ^ dataIn(7)
lfsr_c(16) := lfsr_q( 8) ^ lfsr_q(24) ^ lfsr_q(28) ^ lfsr_q(29) ^ dataIn(0) ^ dataIn(4) ^ dataIn(5)
lfsr_c(17) := lfsr_q( 9) ^ lfsr_q(25) ^ lfsr_q(29) ^ lfsr_q(30) ^ dataIn(1) ^ dataIn(5) ^ dataIn(6)
lfsr_c(18) := lfsr_q(10) ^ lfsr_q(26) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(2) ^ dataIn(6) ^ dataIn(7)
lfsr_c(19) := lfsr_q(11) ^ lfsr_q(27) ^ lfsr_q(31) ^ dataIn(3) ^ dataIn(7)
lfsr_c(20) := lfsr_q(12) ^ lfsr_q(28) ^ dataIn(4)
lfsr_c(21) := lfsr_q(13) ^ lfsr_q(29) ^ dataIn(5)
lfsr_c(22) := lfsr_q(14) ^ lfsr_q(24) ^ dataIn(0)
lfsr_c(23) := lfsr_q(15) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(1) ^ dataIn(6)
lfsr_c(24) := lfsr_q(16) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(2) ^ dataIn(7)
lfsr_c(25) := lfsr_q(17) ^ lfsr_q(26) ^ lfsr_q(27) ^ dataIn(2) ^ dataIn(3)
lfsr_c(26) := lfsr_q(18) ^ lfsr_q(24) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(3) ^ dataIn(4) ^ dataIn(6)
lfsr_c(27) := lfsr_q(19) ^ lfsr_q(25) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(4) ^ dataIn(5) ^ dataIn(7)
lfsr_c(28) := lfsr_q(20) ^ lfsr_q(26) ^ lfsr_q(29) ^ lfsr_q(30) ^ dataIn(2) ^ dataIn(5) ^ dataIn(6)
lfsr_c(29) := lfsr_q(21) ^ lfsr_q(27) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(3) ^ dataIn(6) ^ dataIn(7)
lfsr_c(30) := lfsr_q(22) ^ lfsr_q(28) ^ lfsr_q(31) ^ dataIn(4) ^ dataIn(7)
lfsr_c(31) := lfsr_q(23) ^ lfsr_q(29) ^ dataIn(5)
}
package BACK
import chisel3._
import chisel3.util._
//-----------------------------------------------------------------------------
// 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[7: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;
//-----------------------------------------------------------------------------
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 )
// 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 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))
dataIn := Cat(io.dataIn.asBools)
lfsr_c( 0) := lfsr_q(24) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(6)
lfsr_c( 1) := lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(0) ^ dataIn(1) ^ dataIn(6) ^ dataIn(7)
lfsr_c( 2) := lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(0) ^ dataIn(1) ^ dataIn(2) ^ dataIn(6) ^ dataIn(7)
lfsr_c( 3) := lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(2) ^ dataIn(3) ^ dataIn(7)
lfsr_c( 4) := lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(2) ^ dataIn(3) ^ dataIn(4) ^ dataIn(6)
lfsr_c( 5) := lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(0) ^ dataIn(1) ^ dataIn(3) ^ dataIn(4) ^ dataIn(5) ^ dataIn(6) ^ dataIn(7)
lfsr_c( 6) := lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(2) ^ dataIn(4) ^ dataIn(5) ^ dataIn(6) ^ dataIn(7)
lfsr_c( 7) := lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(31) ^ dataIn(0) ^ dataIn(2) ^ dataIn(3) ^ dataIn(5) ^ dataIn(7)
lfsr_c( 8) := lfsr_q( 0) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(28) ^ dataIn(0) ^ dataIn(1) ^ dataIn(3) ^ dataIn(4)
lfsr_c( 9) := lfsr_q( 1) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ dataIn(1) ^ dataIn(2) ^ dataIn(4) ^ dataIn(5)
lfsr_c(10) := lfsr_q( 2) ^ lfsr_q(24) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ dataIn(0) ^ dataIn(2) ^ dataIn(3) ^ dataIn(5)
lfsr_c(11) := lfsr_q( 3) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(27) ^ lfsr_q(28) ^ dataIn(0) ^ dataIn(1) ^ dataIn(3) ^ dataIn(4)
lfsr_c(12) := lfsr_q( 4) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(1) ^ dataIn(2) ^ dataIn(4) ^ dataIn(5) ^ dataIn(6)
lfsr_c(13) := lfsr_q( 5) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(29) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(2) ^ dataIn(3) ^ dataIn(5) ^ dataIn(6) ^ dataIn(7)
lfsr_c(14) := lfsr_q( 6) ^ lfsr_q(26) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(2) ^ dataIn(3) ^ dataIn(4) ^ dataIn(6) ^ dataIn(7)
lfsr_c(15) := lfsr_q( 7) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ dataIn(3) ^ dataIn(4) ^ dataIn(5) ^ dataIn(7)
lfsr_c(16) := lfsr_q( 8) ^ lfsr_q(24) ^ lfsr_q(28) ^ lfsr_q(29) ^ dataIn(0) ^ dataIn(4) ^ dataIn(5)
lfsr_c(17) := lfsr_q( 9) ^ lfsr_q(25) ^ lfsr_q(29) ^ lfsr_q(30) ^ dataIn(1) ^ dataIn(5) ^ dataIn(6)
lfsr_c(18) := lfsr_q(10) ^ lfsr_q(26) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(2) ^ dataIn(6) ^ dataIn(7)
lfsr_c(19) := lfsr_q(11) ^ lfsr_q(27) ^ lfsr_q(31) ^ dataIn(3) ^ dataIn(7)
lfsr_c(20) := lfsr_q(12) ^ lfsr_q(28) ^ dataIn(4)
lfsr_c(21) := lfsr_q(13) ^ lfsr_q(29) ^ dataIn(5)
lfsr_c(22) := lfsr_q(14) ^ lfsr_q(24) ^ dataIn(0)
lfsr_c(23) := lfsr_q(15) ^ lfsr_q(24) ^ lfsr_q(25) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(1) ^ dataIn(6)
lfsr_c(24) := lfsr_q(16) ^ lfsr_q(25) ^ lfsr_q(26) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(2) ^ dataIn(7)
lfsr_c(25) := lfsr_q(17) ^ lfsr_q(26) ^ lfsr_q(27) ^ dataIn(2) ^ dataIn(3)
lfsr_c(26) := lfsr_q(18) ^ lfsr_q(24) ^ lfsr_q(27) ^ lfsr_q(28) ^ lfsr_q(30) ^ dataIn(0) ^ dataIn(3) ^ dataIn(4) ^ dataIn(6)
lfsr_c(27) := lfsr_q(19) ^ lfsr_q(25) ^ lfsr_q(28) ^ lfsr_q(29) ^ lfsr_q(31) ^ dataIn(1) ^ dataIn(4) ^ dataIn(5) ^ dataIn(7)
lfsr_c(28) := lfsr_q(20) ^ lfsr_q(26) ^ lfsr_q(29) ^ lfsr_q(30) ^ dataIn(2) ^ dataIn(5) ^ dataIn(6)
lfsr_c(29) := lfsr_q(21) ^ lfsr_q(27) ^ lfsr_q(30) ^ lfsr_q(31) ^ dataIn(3) ^ dataIn(6) ^ dataIn(7)
lfsr_c(30) := lfsr_q(22) ^ lfsr_q(28) ^ lfsr_q(31) ^ dataIn(4) ^ dataIn(7)
lfsr_c(31) := lfsr_q(23) ^ lfsr_q(29) ^ dataIn(5)
}