优化信号线命名negedge_sck
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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 //地址1,cmd
|
||||
} .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 //地址1,cmd
|
||||
} .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{
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
@@ -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 //地址1,cmd
|
||||
} .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 //地址1,cmd
|
||||
} .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 //地址1,cmd
|
||||
} .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 //地址1,cmd
|
||||
} .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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,83 +1,83 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
class FDRegInit[T<:Data](init: T, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean){
|
||||
private val pReg = withClockAndReset(pclk, reset) { RegInit( init ) }
|
||||
private val nReg = withClockAndReset(nclk, reset) { RegInit( 0.U.asTypeOf(init) ) }
|
||||
|
||||
val value: T =
|
||||
if( !mode ){ pReg }
|
||||
else { (pReg.asUInt ^ nReg.asUInt).asTypeOf(init) }
|
||||
|
||||
|
||||
private val next = WireDefault(value)
|
||||
|
||||
def :=(d:T): Unit = { next := d }
|
||||
|
||||
if( !mode ){ pReg := next } else { pReg := (nReg.asUInt ^ next.asUInt).asTypeOf(init) }
|
||||
nReg := (pReg.asUInt ^ next.asUInt).asTypeOf(init)
|
||||
|
||||
def apply(): T = value
|
||||
|
||||
}
|
||||
|
||||
object FDRegInit{
|
||||
def apply[T<:Data](init: T, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean): FDRegInit[T] = {
|
||||
new FDRegInit(init, pclk, nclk, reset, mode)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class FDRegNext[T<:Data](d: T, init: T, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean ){
|
||||
private val pReg = withClockAndReset(pclk, reset) { RegInit( init ) }
|
||||
private val nReg = withClockAndReset(nclk, reset) { RegInit( 0.U.asTypeOf(init) ) }
|
||||
|
||||
if( !mode ) { pReg := d } else { pReg := (d.asUInt ^ nReg.asUInt).asTypeOf(init) }
|
||||
nReg := (d.asUInt ^ pReg.asUInt).asTypeOf(init)
|
||||
|
||||
val value: T =
|
||||
if( !mode ){ pReg }
|
||||
else { (pReg.asUInt ^ nReg.asUInt).asTypeOf(init) }
|
||||
|
||||
def apply(): T = value
|
||||
}
|
||||
|
||||
|
||||
object FDRegNext{
|
||||
def apply[T<:Data]( d: T, init: T, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean ): T = {
|
||||
new FDRegNext(d, init, pclk, nclk, reset, mode ).apply()
|
||||
}
|
||||
}
|
||||
|
||||
class FDShiftRegisters[T<:Data]( in: T, n: Int, init: T, en: Bool, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean ){
|
||||
private val pRegs = withClockAndReset(pclk, reset) { RegInit(VecInit(Seq.fill(n)( init ))) }
|
||||
private val nRegs = withClockAndReset(nclk, reset) { RegInit(VecInit(Seq.fill(n)( 0.U.asTypeOf(init)))) }
|
||||
|
||||
// 移位逻辑:首位采样输入,其他依次移位
|
||||
if( !mode ){ pRegs(0) := in } else { pRegs(0) := (in.asUInt ^ nRegs(0).asUInt).asTypeOf(init) }
|
||||
for(i <- 1 until n) {
|
||||
if( !mode ){ pRegs(i) := pRegs(i-1) }
|
||||
else { pRegs(i) := (pRegs(i-1).asUInt ^ nRegs(i).asUInt).asTypeOf(init)}
|
||||
}
|
||||
|
||||
nRegs(0) := (in.asUInt ^ pRegs(0).asUInt).asTypeOf(init)
|
||||
for(i <- 1 until n) {
|
||||
nRegs(i) := (nRegs(i-1).asUInt ^ pRegs(i).asUInt).asTypeOf(init)
|
||||
}
|
||||
|
||||
// 输出为 pRegs 与 nRegs 异或
|
||||
def apply(): Seq[T] =
|
||||
if( !mode ){ pRegs }
|
||||
else (pRegs zip nRegs).map{ case (a, b) => (a.asUInt ^ b.asUInt).asTypeOf(init) }
|
||||
}
|
||||
|
||||
|
||||
object FDShiftRegisters{
|
||||
def apply[T<:Data]( in: T, n: Int, init: T, en: Bool, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean ): Seq[T] = {
|
||||
new FDShiftRegisters( in, n, init, en, pclk, nclk, reset, mode ).apply()
|
||||
}
|
||||
}
|
||||
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
class FDRegInit[T<:Data](init: T, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean){
|
||||
private val pReg = withClockAndReset(pclk, reset) { RegInit( init ) }
|
||||
private val nReg = withClockAndReset(nclk, reset) { RegInit( 0.U.asTypeOf(init) ) }
|
||||
|
||||
val value: T =
|
||||
if( !mode ){ pReg }
|
||||
else { (pReg.asUInt ^ nReg.asUInt).asTypeOf(init) }
|
||||
|
||||
|
||||
private val next = WireDefault(value)
|
||||
|
||||
def :=(d:T): Unit = { next := d }
|
||||
|
||||
if( !mode ){ pReg := next } else { pReg := (nReg.asUInt ^ next.asUInt).asTypeOf(init) }
|
||||
nReg := (pReg.asUInt ^ next.asUInt).asTypeOf(init)
|
||||
|
||||
def apply(): T = value
|
||||
|
||||
}
|
||||
|
||||
object FDRegInit{
|
||||
def apply[T<:Data](init: T, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean): FDRegInit[T] = {
|
||||
new FDRegInit(init, pclk, nclk, reset, mode)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class FDRegNext[T<:Data](d: T, init: T, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean ){
|
||||
private val pReg = withClockAndReset(pclk, reset) { RegInit( init ) }
|
||||
private val nReg = withClockAndReset(nclk, reset) { RegInit( 0.U.asTypeOf(init) ) }
|
||||
|
||||
if( !mode ) { pReg := d } else { pReg := (d.asUInt ^ nReg.asUInt).asTypeOf(init) }
|
||||
nReg := (d.asUInt ^ pReg.asUInt).asTypeOf(init)
|
||||
|
||||
val value: T =
|
||||
if( !mode ){ pReg }
|
||||
else { (pReg.asUInt ^ nReg.asUInt).asTypeOf(init) }
|
||||
|
||||
def apply(): T = value
|
||||
}
|
||||
|
||||
|
||||
object FDRegNext{
|
||||
def apply[T<:Data]( d: T, init: T, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean ): T = {
|
||||
new FDRegNext(d, init, pclk, nclk, reset, mode ).apply()
|
||||
}
|
||||
}
|
||||
|
||||
class FDShiftRegisters[T<:Data]( in: T, n: Int, init: T, en: Bool, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean ){
|
||||
private val pRegs = withClockAndReset(pclk, reset) { RegInit(VecInit(Seq.fill(n)( init ))) }
|
||||
private val nRegs = withClockAndReset(nclk, reset) { RegInit(VecInit(Seq.fill(n)( 0.U.asTypeOf(init)))) }
|
||||
|
||||
// 移位逻辑:首位采样输入,其他依次移位
|
||||
if( !mode ){ pRegs(0) := in } else { pRegs(0) := (in.asUInt ^ nRegs(0).asUInt).asTypeOf(init) }
|
||||
for(i <- 1 until n) {
|
||||
if( !mode ){ pRegs(i) := pRegs(i-1) }
|
||||
else { pRegs(i) := (pRegs(i-1).asUInt ^ nRegs(i).asUInt).asTypeOf(init)}
|
||||
}
|
||||
|
||||
nRegs(0) := (in.asUInt ^ pRegs(0).asUInt).asTypeOf(init)
|
||||
for(i <- 1 until n) {
|
||||
nRegs(i) := (nRegs(i-1).asUInt ^ pRegs(i).asUInt).asTypeOf(init)
|
||||
}
|
||||
|
||||
// 输出为 pRegs 与 nRegs 异或
|
||||
def apply(): Seq[T] =
|
||||
if( !mode ){ pRegs }
|
||||
else (pRegs zip nRegs).map{ case (a, b) => (a.asUInt ^ b.asUInt).asTypeOf(init) }
|
||||
}
|
||||
|
||||
|
||||
object FDShiftRegisters{
|
||||
def apply[T<:Data]( in: T, n: Int, init: T, en: Bool, pclk: Clock, nclk: Clock, reset: AsyncReset, mode: Boolean ): Seq[T] = {
|
||||
new FDShiftRegisters( in, n, init, en, pclk, nclk, reset, mode ).apply()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,170 +1,170 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
|
||||
class SimCDR extends Module with RequireAsyncReset{
|
||||
val io = IO(new Bundle{
|
||||
val data = Input( UInt(8.W) )
|
||||
|
||||
val multiCLK = Input(Vec(16, Bool()))
|
||||
|
||||
val flush = Input(Bool())
|
||||
|
||||
val isSuccess = Output(Bool())
|
||||
val isFailed = Output(Bool())
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
val cdrInAxis = Module(new CDRInAxis)
|
||||
val cdrInSample = Module(new CDRInMultiSample(clkNum = 4))
|
||||
|
||||
val cdrOut = Module(new CDROut)
|
||||
|
||||
val dataCnt = RegInit(0.U(12.W))
|
||||
val payloadLen = RegInit(("hFFF".U)(12.W))
|
||||
|
||||
val b4b5Encoder = Module(new b4b5DualEncode)
|
||||
val b4b5Decoder = Module(new b4b5DualDecode)
|
||||
|
||||
val b8b10Encoder = Module(new b8b10Encode)
|
||||
val b8b10Decoder = Module(new b8b10Decode)
|
||||
|
||||
val wPtr = RegInit(0.U(12.W))
|
||||
val rPtr = withClockAndReset( io.multiCLK(0).asClock, reset ) { RegInit(0.U(12.W)) }
|
||||
|
||||
val asyncFifo = Module(new ShareSRAM2k)
|
||||
|
||||
when( cdrOut.io.axis.fire & dataCnt === 0.U ){
|
||||
payloadLen := Cat( io.data, 0.U(4.W) )
|
||||
} .elsewhen( cdrOut.io.axis.fire & dataCnt === 1.U ){
|
||||
payloadLen := Cat( payloadLen(11,4), io.data(7,4) ) + 4.U + 4.U
|
||||
}
|
||||
|
||||
when( cdrOut.io.axis.fire ){
|
||||
when( dataCnt >= payloadLen - 1.U ){
|
||||
dataCnt := 0.U
|
||||
} .otherwise{
|
||||
dataCnt := dataCnt + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cdrOut.io.flush := io.flush
|
||||
|
||||
cdrInAxis.clock := io.multiCLK(0).asClock
|
||||
cdrInSample.clock := io.multiCLK(0).asClock
|
||||
cdrInAxis.io.flush := io.flush
|
||||
|
||||
// cdrInSample.multiCLK := io.multiCLK
|
||||
cdrInSample.multiCLK(0) := io.multiCLK(0)
|
||||
cdrInSample.multiCLK(1) := io.multiCLK(4)
|
||||
cdrInSample.multiCLK(2) := io.multiCLK(8)
|
||||
cdrInSample.multiCLK(3) := io.multiCLK(12)
|
||||
cdrInAxis.io.syncSerDat := cdrInSample.io.syncSerDat
|
||||
|
||||
|
||||
cdrInSample.io.serDat := cdrOut.io.serDat
|
||||
|
||||
|
||||
|
||||
val isTxEnd = cdrOut.io.axis.fire & cdrOut.io.axis.bits.tlast
|
||||
|
||||
cdrOut.io.axis.valid := ~io.flush & ShiftRegisters( ~isTxEnd, 32 ).reduce(_&_)
|
||||
cdrOut.io.axis.bits.tdata := io.data
|
||||
cdrOut.io.axis.bits.tuser := false.B
|
||||
cdrOut.io.axis.bits.tlast := dataCnt === (payloadLen - 1.U)
|
||||
|
||||
|
||||
|
||||
|
||||
cdrInAxis.io.axis.ready := true.B
|
||||
|
||||
io.isFailed := cdrInAxis.io.axis.fire & (asyncFifo.io.datar =/= cdrInAxis.io.axis.bits.tdata)
|
||||
io.isSuccess := cdrInAxis.io.axis.fire & cdrInAxis.io.axis.bits.tlast
|
||||
|
||||
|
||||
|
||||
|
||||
val isUsing8b10b = true.B
|
||||
|
||||
|
||||
when( isUsing8b10b ){
|
||||
b8b10Encoder.io <> cdrOut.io.encode
|
||||
b8b10Decoder.io <> cdrInAxis.io.decode
|
||||
|
||||
b4b5Encoder.io.isEnable := false.B
|
||||
b4b5Encoder.io.dataIn := 0.U
|
||||
b4b5Decoder.io.dataIn := 0.U
|
||||
} .otherwise{
|
||||
b4b5Encoder.io <> cdrOut.io.encode
|
||||
b4b5Decoder.io <> cdrInAxis.io.decode
|
||||
|
||||
b8b10Encoder.io.isEnable := false.B
|
||||
b8b10Encoder.io.dataIn := 0.U
|
||||
b8b10Decoder.io.dataIn := 0.U
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
asyncFifo.io.clockw := clock.asBool
|
||||
asyncFifo.io.dataw := io.data
|
||||
asyncFifo.io.addrw := wPtr(10,0)
|
||||
asyncFifo.io.enw := cdrOut.io.axis.fire
|
||||
|
||||
asyncFifo.io.clockr := io.multiCLK(0)
|
||||
asyncFifo.io.addrr := rPtr(10,0)
|
||||
asyncFifo.io.enr := true.B
|
||||
|
||||
when( cdrOut.io.axis.fire ){
|
||||
wPtr := wPtr + 1.U
|
||||
}
|
||||
|
||||
when( cdrInAxis.io.axis.fire ){
|
||||
rPtr := rPtr + 1.U
|
||||
}
|
||||
|
||||
val isFull = (wPtr ^ rPtr) === (1.U << log2Ceil(2048))
|
||||
assert(~isFull)
|
||||
|
||||
|
||||
|
||||
|
||||
val coverData = RegInit(VecInit(Seq.fill(512){false.B}))
|
||||
when( cdrOut.io.axis.fire ){
|
||||
for( i <- 0 until 256 ){
|
||||
when( io.data === i.U ){
|
||||
when( b8b10Encoder.rdTest ){
|
||||
coverData(i) := true.B
|
||||
} .otherwise{
|
||||
coverData(256+i) := true.B
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// val coverData = RegInit(VecInit(Seq.fill(256){false.B}))
|
||||
// when( cdrOut.io.axis.fire ){
|
||||
// for( i <- 0 until 256 ){
|
||||
// when( io.data === i.U ){
|
||||
// coverData(i) := true.B
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
val coverage = PopCount(coverData.asUInt)
|
||||
when( io.isSuccess ){
|
||||
printf( cf"Coverage: ${coverage}\n")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
|
||||
class SimCDR extends Module with RequireAsyncReset{
|
||||
val io = IO(new Bundle{
|
||||
val data = Input( UInt(8.W) )
|
||||
|
||||
val multiCLK = Input(Vec(16, Bool()))
|
||||
|
||||
val flush = Input(Bool())
|
||||
|
||||
val isSuccess = Output(Bool())
|
||||
val isFailed = Output(Bool())
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
val cdrInAxis = Module(new CDRInAxis)
|
||||
val cdrInSample = Module(new CDRInMultiSample(clkNum = 4))
|
||||
|
||||
val cdrOut = Module(new CDROut)
|
||||
|
||||
val dataCnt = RegInit(0.U(12.W))
|
||||
val payloadLen = RegInit(("hFFF".U)(12.W))
|
||||
|
||||
val b4b5Encoder = Module(new b4b5DualEncode)
|
||||
val b4b5Decoder = Module(new b4b5DualDecode)
|
||||
|
||||
val b8b10Encoder = Module(new b8b10Encode)
|
||||
val b8b10Decoder = Module(new b8b10Decode)
|
||||
|
||||
val wPtr = RegInit(0.U(12.W))
|
||||
val rPtr = withClockAndReset( io.multiCLK(0).asClock, reset ) { RegInit(0.U(12.W)) }
|
||||
|
||||
val asyncFifo = Module(new ShareSRAM2k)
|
||||
|
||||
when( cdrOut.io.axis.fire & dataCnt === 0.U ){
|
||||
payloadLen := Cat( io.data, 0.U(4.W) )
|
||||
} .elsewhen( cdrOut.io.axis.fire & dataCnt === 1.U ){
|
||||
payloadLen := Cat( payloadLen(11,4), io.data(7,4) ) + 4.U + 4.U
|
||||
}
|
||||
|
||||
when( cdrOut.io.axis.fire ){
|
||||
when( dataCnt >= payloadLen - 1.U ){
|
||||
dataCnt := 0.U
|
||||
} .otherwise{
|
||||
dataCnt := dataCnt + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cdrOut.io.flush := io.flush
|
||||
|
||||
cdrInAxis.clock := io.multiCLK(0).asClock
|
||||
cdrInSample.clock := io.multiCLK(0).asClock
|
||||
cdrInAxis.io.flush := io.flush
|
||||
|
||||
// cdrInSample.multiCLK := io.multiCLK
|
||||
cdrInSample.multiCLK(0) := io.multiCLK(0)
|
||||
cdrInSample.multiCLK(1) := io.multiCLK(4)
|
||||
cdrInSample.multiCLK(2) := io.multiCLK(8)
|
||||
cdrInSample.multiCLK(3) := io.multiCLK(12)
|
||||
cdrInAxis.io.syncSerDat := cdrInSample.io.syncSerDat
|
||||
|
||||
|
||||
cdrInSample.io.serDat := cdrOut.io.serDat
|
||||
|
||||
|
||||
|
||||
val isTxEnd = cdrOut.io.axis.fire & cdrOut.io.axis.bits.tlast
|
||||
|
||||
cdrOut.io.axis.valid := ~io.flush & ShiftRegisters( ~isTxEnd, 32 ).reduce(_&_)
|
||||
cdrOut.io.axis.bits.tdata := io.data
|
||||
cdrOut.io.axis.bits.tuser := false.B
|
||||
cdrOut.io.axis.bits.tlast := dataCnt === (payloadLen - 1.U)
|
||||
|
||||
|
||||
|
||||
|
||||
cdrInAxis.io.axis.ready := true.B
|
||||
|
||||
io.isFailed := cdrInAxis.io.axis.fire & (asyncFifo.io.datar =/= cdrInAxis.io.axis.bits.tdata)
|
||||
io.isSuccess := cdrInAxis.io.axis.fire & cdrInAxis.io.axis.bits.tlast
|
||||
|
||||
|
||||
|
||||
|
||||
val isUsing8b10b = true.B
|
||||
|
||||
|
||||
when( isUsing8b10b ){
|
||||
b8b10Encoder.io <> cdrOut.io.encode
|
||||
b8b10Decoder.io <> cdrInAxis.io.decode
|
||||
|
||||
b4b5Encoder.io.isEnable := false.B
|
||||
b4b5Encoder.io.dataIn := 0.U
|
||||
b4b5Decoder.io.dataIn := 0.U
|
||||
} .otherwise{
|
||||
b4b5Encoder.io <> cdrOut.io.encode
|
||||
b4b5Decoder.io <> cdrInAxis.io.decode
|
||||
|
||||
b8b10Encoder.io.isEnable := false.B
|
||||
b8b10Encoder.io.dataIn := 0.U
|
||||
b8b10Decoder.io.dataIn := 0.U
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
asyncFifo.io.clockw := clock.asBool
|
||||
asyncFifo.io.dataw := io.data
|
||||
asyncFifo.io.addrw := wPtr(10,0)
|
||||
asyncFifo.io.enw := cdrOut.io.axis.fire
|
||||
|
||||
asyncFifo.io.clockr := io.multiCLK(0)
|
||||
asyncFifo.io.addrr := rPtr(10,0)
|
||||
asyncFifo.io.enr := true.B
|
||||
|
||||
when( cdrOut.io.axis.fire ){
|
||||
wPtr := wPtr + 1.U
|
||||
}
|
||||
|
||||
when( cdrInAxis.io.axis.fire ){
|
||||
rPtr := rPtr + 1.U
|
||||
}
|
||||
|
||||
val isFull = (wPtr ^ rPtr) === (1.U << log2Ceil(2048))
|
||||
assert(~isFull)
|
||||
|
||||
|
||||
|
||||
|
||||
val coverData = RegInit(VecInit(Seq.fill(512){false.B}))
|
||||
when( cdrOut.io.axis.fire ){
|
||||
for( i <- 0 until 256 ){
|
||||
when( io.data === i.U ){
|
||||
when( b8b10Encoder.rdTest ){
|
||||
coverData(i) := true.B
|
||||
} .otherwise{
|
||||
coverData(256+i) := true.B
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// val coverData = RegInit(VecInit(Seq.fill(256){false.B}))
|
||||
// when( cdrOut.io.axis.fire ){
|
||||
// for( i <- 0 until 256 ){
|
||||
// when( io.data === i.U ){
|
||||
// coverData(i) := true.B
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
val coverage = PopCount(coverData.asUInt)
|
||||
when( io.isSuccess ){
|
||||
printf( cf"Coverage: ${coverage}\n")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
package test
|
||||
|
||||
|
||||
import BACK._
|
||||
|
||||
|
||||
import chisel3._
|
||||
import chisel3.stage._
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
object testShinModule extends App {
|
||||
(new chisel3.stage.ChiselStage).execute( Array("--target-dir", "generated/shin/", "-e", "verilog" ) ++ args, Seq(
|
||||
ChiselGeneratorAnnotation(() => { new ShinTop }),
|
||||
))
|
||||
|
||||
(new chisel3.stage.ChiselStage).execute( Array("--target-dir", "generated/SimCDR/", "-e", "verilog" ) ++ args, Seq(
|
||||
ChiselGeneratorAnnotation(() => { new SimCDR }),
|
||||
))
|
||||
}
|
||||
|
||||
package test
|
||||
|
||||
|
||||
import BACK._
|
||||
|
||||
|
||||
import chisel3._
|
||||
import chisel3.stage._
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
object testShinModule extends App {
|
||||
(new chisel3.stage.ChiselStage).execute( Array("--target-dir", "generated/shin/", "-e", "verilog" ) ++ args, Seq(
|
||||
ChiselGeneratorAnnotation(() => { new ShinTop }),
|
||||
))
|
||||
|
||||
(new chisel3.stage.ChiselStage).execute( Array("--target-dir", "generated/SimCDR/", "-e", "verilog" ) ++ args, Seq(
|
||||
ChiselGeneratorAnnotation(() => { new SimCDR }),
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user