new version
This commit is contained in:
@@ -21,7 +21,8 @@ class FSMC_Port_Bundle extends Bundle{
|
||||
class BackBoardMstIO extends Bundle{
|
||||
val FSMC = new FSMC_Port_Bundle
|
||||
|
||||
val reset = Input(Bool())
|
||||
// val reset = Input(Bool())
|
||||
val reset_calib = Input(Bool())
|
||||
val oser_pclk = Input(Bool())
|
||||
val oser_fclk = Input(Bool())
|
||||
val ides_pclk = Input(Bool())
|
||||
@@ -29,27 +30,70 @@ class BackBoardMstIO extends Bundle{
|
||||
|
||||
val lvds_down_dout = Output(Bool())
|
||||
val lvds_up_din = Input(Bool())
|
||||
|
||||
val cdrErr = Output(Bool())
|
||||
val crcErr = Output(Bool())
|
||||
val linkErr = Output(Bool())
|
||||
}
|
||||
|
||||
// class Master_Status_Bundle extends Bundle{
|
||||
// val zero = UInt(11.W)
|
||||
// val cdrErr = Bool()
|
||||
// val crcErr = Bool()
|
||||
// val linkErr = Bool()
|
||||
// val synchronize = Bool()
|
||||
// val initialization = Bool()
|
||||
// }
|
||||
|
||||
class BackBoardMstBase extends RawModule{
|
||||
// class Master_Control_Bundle extends Bundle{
|
||||
// val zero = UInt(13.W)
|
||||
// val transmit = Bool()
|
||||
// val synchronize = Bool()
|
||||
// val initialization = Bool()
|
||||
// }
|
||||
|
||||
|
||||
class BackBoardMstBase extends Module{ //10M
|
||||
val io: BackBoardMstIO = IO(new BackBoardMstIO)
|
||||
|
||||
|
||||
|
||||
val lvdsMst = Module(new Lvds_Bus_Master)
|
||||
val mirrorDown = Module(new MirrorSRAMDown())
|
||||
val mirrorUp = Module(new MirrorSRAMUp())
|
||||
|
||||
val status = Wire(UInt(16.W))
|
||||
val slvNum = Wire(UInt(5.W))
|
||||
val statusCDRErr = RegInit( false.B )
|
||||
val statusCRCErr = RegInit( false.B )
|
||||
val statusLinkErr = RegInit( false.B )
|
||||
val statusSynch = RegInit( false.B )
|
||||
val statusInit = RegInit( false.B )
|
||||
|
||||
val ctrlTransmit = RegInit( false.B )
|
||||
val ctrlCDRErr = RegInit( false.B )
|
||||
val ctrlCRCErr = RegInit( false.B )
|
||||
val ctrlLinkErr = RegInit( false.B )
|
||||
val ctrlSynch = RegInit( false.B )
|
||||
val ctrlInit = RegInit( false.B )
|
||||
|
||||
val slvNum = RegInit(0.U(6.W))
|
||||
val slvOffLine = RegInit(0.U(6.W))
|
||||
|
||||
lvdsMst.io.rst_n := ~reset.asBool
|
||||
lvdsMst.io.reset_calib := io.reset_calib
|
||||
lvdsMst.io.oser_pclk := io.oser_pclk
|
||||
lvdsMst.io.oser_fclk := io.oser_fclk
|
||||
lvdsMst.io.ides_pclk := io.ides_pclk
|
||||
lvdsMst.io.ides_fclk := io.ides_fclk
|
||||
|
||||
io.lvds_down_dout := lvdsMst.io.lvds_down_dout
|
||||
lvdsMst.io.lvds_up_din := io.lvds_up_din
|
||||
|
||||
|
||||
mirrorDown.io.clockw := io.ides_pclk.asBool
|
||||
|
||||
|
||||
mirrorDown.io.clockw := io.oser_pclk.asBool
|
||||
mirrorDown.io.clockr := io.oser_pclk.asBool
|
||||
|
||||
mirrorUp.io.clockw := io.oser_pclk.asBool
|
||||
mirrorUp.io.clockr := io.ides_pclk.asBool
|
||||
mirrorUp.io.clockr := io.oser_pclk.asBool
|
||||
|
||||
}
|
||||
|
||||
@@ -58,175 +102,331 @@ class BackBoardMstBase extends RawModule{
|
||||
|
||||
trait BackBoardMstFSMC{ this: BackBoardMstBase =>
|
||||
|
||||
withClockAndReset( io.ides_pclk.asClock, io.reset ){
|
||||
val statusReg = RegInit(0.U(16.W)); status := statusReg
|
||||
val slvNumReg = RegInit(1.U(5.W)); slvNum := slvNumReg
|
||||
|
||||
val fsmcAddrSync = ShiftRegister( io.FSMC.addr, 2, 0.U, true.B )
|
||||
val fsmcdataInSync = ShiftRegister( io.FSMC.dataIn, 2, 0.U, true.B )
|
||||
val fsmcCEnSync = ShiftRegister( io.FSMC.cen, 2, true.B, true.B )
|
||||
val fsmcOEnSync = ShiftRegister( io.FSMC.oen, 2, true.B, true.B )
|
||||
val fsmcWEnSync = ShiftRegister( io.FSMC.wen, 2, true.B, true.B )
|
||||
|
||||
io.FSMC.dataOEn := io.FSMC.oen
|
||||
|
||||
|
||||
val isAccessSRAM = ~fsmcAddrSync.extract(9)
|
||||
val isAccessReg = fsmcAddrSync.extract(9)
|
||||
val activeAddr = fsmcAddrSync(8,0)
|
||||
val regOut = Wire(UInt(16.W))
|
||||
|
||||
val fsmcAddrSync = ShiftRegister( io.FSMC.addr, 2, 0.U, true.B )
|
||||
val fsmcdataInSync = ShiftRegister( io.FSMC.dataIn, 2, 0.U, true.B )
|
||||
val fsmcCEnSync = ShiftRegister( io.FSMC.cen, 2, true.B, true.B )
|
||||
val fsmcOEnSync = ShiftRegister( io.FSMC.oen, 2, true.B, true.B )
|
||||
val fsmcWEnSync = ShiftRegister( io.FSMC.wen, 2, true.B, true.B )
|
||||
|
||||
io.FSMC.dataOEn := io.FSMC.oen
|
||||
|
||||
|
||||
val isAccessSRAM = ~fsmcAddrSync.extract(9)
|
||||
val isAccessReg = fsmcAddrSync.extract(9)
|
||||
val activeAddr = fsmcAddrSync(8,0)
|
||||
val regOut = Wire(UInt(16.W))
|
||||
|
||||
mirrorDown.io.enw := (~fsmcCEnSync & isAccessSRAM & (~fsmcWEnSync) )
|
||||
mirrorDown.io.addrw := activeAddr
|
||||
mirrorDown.io.dataw := fsmcdataInSync
|
||||
|
||||
|
||||
mirrorDown.io.enw := (~fsmcCEnSync & isAccessSRAM & (~fsmcWEnSync) )
|
||||
mirrorDown.io.addrw := activeAddr
|
||||
mirrorDown.io.dataw := fsmcdataInSync
|
||||
|
||||
|
||||
mirrorUp.io.enr := (~fsmcCEnSync & isAccessSRAM & (~fsmcOEnSync) )
|
||||
mirrorUp.io.addrr := activeAddr
|
||||
mirrorUp.io.enr := (~fsmcCEnSync & isAccessSRAM & (~fsmcOEnSync) )
|
||||
mirrorUp.io.addrr := activeAddr
|
||||
|
||||
|
||||
|
||||
|
||||
io.FSMC.dataOut := Mux( isAccessReg, regOut, mirrorUp.io.datar)
|
||||
io.FSMC.dataOut := Mux( isAccessReg, regOut, mirrorUp.io.datar)
|
||||
|
||||
regOut := Mux1H(Seq(
|
||||
( activeAddr === 0.U) -> status,
|
||||
( activeAddr === 1.U) -> slvNum,
|
||||
))
|
||||
regOut := Mux1H(Seq(
|
||||
( activeAddr === 0.U) ->
|
||||
Cat(
|
||||
statusCDRErr ,
|
||||
statusCRCErr ,
|
||||
statusLinkErr,
|
||||
statusSynch ,
|
||||
statusInit
|
||||
),
|
||||
( activeAddr === 1.U) ->
|
||||
Cat(
|
||||
ctrlTransmit,
|
||||
ctrlCDRErr ,
|
||||
ctrlCRCErr ,
|
||||
ctrlLinkErr ,
|
||||
ctrlSynch ,
|
||||
ctrlInit
|
||||
),
|
||||
( activeAddr === 2.U) -> slvNum,
|
||||
( activeAddr === 3.U) -> slvOffLine,
|
||||
))
|
||||
|
||||
when( (~fsmcCEnSync & isAccessReg & (~fsmcWEnSync) ) & ( activeAddr === 0.U) ){
|
||||
statusReg := fsmcdataInSync
|
||||
}
|
||||
|
||||
when( (~fsmcCEnSync & isAccessReg & (~fsmcWEnSync) ) & ( activeAddr === 1.U) ){
|
||||
slvNumReg := fsmcdataInSync
|
||||
}
|
||||
// when( (~fsmcCEnSync & isAccessReg & (~fsmcWEnSync) ) & ( activeAddr === 0.U) ){
|
||||
// status := fsmcdataInSync
|
||||
// }
|
||||
|
||||
when( (~fsmcCEnSync & isAccessReg & (~fsmcWEnSync) ) & ( activeAddr === 1.U) ){
|
||||
|
||||
ctrlTransmit := fsmcdataInSync.extract(5)
|
||||
ctrlCDRErr := fsmcdataInSync.extract(4)
|
||||
ctrlCRCErr := fsmcdataInSync.extract(3)
|
||||
ctrlLinkErr := fsmcdataInSync.extract(2)
|
||||
ctrlSynch := fsmcdataInSync.extract(1)
|
||||
ctrlInit := fsmcdataInSync.extract(0)
|
||||
}
|
||||
|
||||
// when( (~fsmcCEnSync & isAccessReg & (~fsmcWEnSync) ) & ( activeAddr === 2.U) ){
|
||||
// slvNum := fsmcdataInSync
|
||||
// }
|
||||
|
||||
when( (~fsmcCEnSync & isAccessReg & (~fsmcWEnSync) ) & ( activeAddr === 3.U) ){
|
||||
slvOffLine := fsmcdataInSync
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
trait BackBoardMstLVDS{ this: BackBoardMstBase =>
|
||||
lvdsMst.io.rst_n := ~io.reset
|
||||
lvdsMst.io.oser_pclk := io.oser_pclk
|
||||
lvdsMst.io.oser_fclk := io.oser_fclk
|
||||
lvdsMst.io.ides_pclk := io.ides_pclk
|
||||
lvdsMst.io.ides_fclk := io.ides_fclk
|
||||
|
||||
io.lvds_down_dout := lvdsMst.io.lvds_down_dout
|
||||
lvdsMst.io.lvds_up_din := io.lvds_up_din
|
||||
abstract class BackBoardMstLVDSBase extends BackBoardMstBase with BackBoardMstFSMC{
|
||||
|
||||
|
||||
val frame_info_update_en = RegInit(false.B)
|
||||
val slave_type_num = RegInit(0.U(8.W))
|
||||
val slave_data_length = RegInit(0.U(8.W))
|
||||
val tx_start = RegInit(false.B)
|
||||
|
||||
lvdsMst.io.frame_info_update_en := frame_info_update_en
|
||||
lvdsMst.io.slave_type_num := slave_type_num
|
||||
lvdsMst.io.slave_data_length := slave_data_length
|
||||
lvdsMst.io.tx_start := tx_start
|
||||
|
||||
val stateCur = RegInit(15.U(4.W))
|
||||
}
|
||||
|
||||
|
||||
trait BackBoardMstLVDSInitialization{ this: BackBoardMstLVDSBase =>
|
||||
|
||||
val isInitCntReset = ( ~RegNext(ctrlInit) & ctrlInit ) | (stateCur === 3.U) | (stateCur === 8.U)
|
||||
val ( _, isInitTimeout ) = Counter(Range( 0,5200), ctrlInit, isInitCntReset)
|
||||
val synchCnt = Reg(UInt(3.W))
|
||||
|
||||
when( isInitTimeout ){
|
||||
|
||||
stateCur := 0.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
slave_type_num := 0.U
|
||||
slave_data_length := 0.U
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
|
||||
lvdsMst.io.tx_start := false.B
|
||||
} .elsewhen( stateCur === 0.U ){
|
||||
stateCur := 1.U
|
||||
|
||||
frame_info_update_en := true.B
|
||||
slave_type_num := Cat( "b00".U(2.W), slvNum )
|
||||
slave_data_length := ((8/8)*16-1).U
|
||||
|
||||
val trigger_wire = Wire(Bool())
|
||||
val stateCur_wire = Wire( UInt(4.W) )
|
||||
tx_start := false.B
|
||||
} .elsewhen( stateCur === 1.U ){ // tx start
|
||||
stateCur := 2.U
|
||||
|
||||
withClockAndReset( io.oser_pclk.asClock, io.reset ){
|
||||
frame_info_update_en := false.B
|
||||
tx_start := true.B
|
||||
|
||||
val stateCur = RegInit(3.U(4.W))
|
||||
stateCur_wire := stateCur
|
||||
} .elsewhen( stateCur === 2.U ){
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
val ( _, trigger ) = Counter(Range( 0,1000) )
|
||||
trigger_wire := trigger
|
||||
when( lvdsMst.io.slave_link_num_valid ){
|
||||
slvNum := lvdsMst.io.slave_link_num(5,0)
|
||||
stateCur := 3.U
|
||||
}
|
||||
|
||||
val isSync = RegInit(false.B)
|
||||
} .elsewhen( stateCur === 3.U ){
|
||||
frame_info_update_en := false.B
|
||||
slave_type_num := 0.U
|
||||
slave_data_length := 0.U
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
val frame_info_update_en = RegInit(false.B)
|
||||
stateCur := 4.U
|
||||
|
||||
} .elsewhen( stateCur === 4.U ){
|
||||
stateCur := 5.U
|
||||
|
||||
val slave_type_num = RegInit(0.U(8.W))
|
||||
val slave_data_length = RegInit(0.U(8.W))
|
||||
val tx_start = RegInit(false.B)
|
||||
frame_info_update_en := true.B
|
||||
slave_type_num := Cat( "b00".U(2.W), slvNum )
|
||||
slave_data_length := ((8/8)*16-1).U
|
||||
|
||||
lvdsMst.io.frame_info_update_en := frame_info_update_en
|
||||
lvdsMst.io.slave_type_num := slave_type_num
|
||||
lvdsMst.io.slave_data_length := slave_data_length
|
||||
lvdsMst.io.tx_start := tx_start
|
||||
tx_start := false.B
|
||||
} .elsewhen( stateCur === 5.U ){ // tx start
|
||||
stateCur := 6.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
tx_start := true.B
|
||||
|
||||
} .elsewhen( stateCur === 6.U ){
|
||||
|
||||
when( trigger ){ //reset
|
||||
stateCur := 0.U
|
||||
tx_start := false.B
|
||||
|
||||
frame_info_update_en := false.B
|
||||
slave_type_num := 0.U
|
||||
slave_data_length := 0.U
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
isSync := ~isSync
|
||||
|
||||
} .elsewhen( stateCur === 0.U ){ //setting
|
||||
stateCur := 1.U
|
||||
|
||||
|
||||
|
||||
frame_info_update_en := true.B
|
||||
slave_type_num := Mux(isSync, Cat( "b000".U(3.W), slvNum ), Cat( "b100".U(3.W), slvNum ) )
|
||||
slave_data_length := ((8/8)*16-1).U
|
||||
|
||||
tx_start := false.B
|
||||
} .elsewhen( stateCur === 1.U ){ // tx start
|
||||
stateCur := 2.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
tx_start := true.B
|
||||
|
||||
} .elsewhen( stateCur === 2.U ){ //waiting for busy drop
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
when( RegNext(lvdsMst.io.downstream_busy, false.B) & ~lvdsMst.io.downstream_busy ){
|
||||
stateCur := 3.U
|
||||
when( lvdsMst.io.slave_link_num_valid ){
|
||||
when( slvNum === lvdsMst.io.slave_link_num(5,0) ){
|
||||
stateCur := 7.U
|
||||
} .otherwise{
|
||||
printf("Initialization failed, waitting for timeout!\n")
|
||||
}
|
||||
}
|
||||
|
||||
} .elsewhen( stateCur === 3.U ){
|
||||
|
||||
} .elsewhen( stateCur === 7.U ){
|
||||
when( ctrlSynch ){
|
||||
stateCur := 8.U
|
||||
synchCnt := 0.U
|
||||
} .otherwise{
|
||||
|
||||
assert(false.B)
|
||||
statusInit := true.B
|
||||
ctrlInit := false.B
|
||||
}
|
||||
|
||||
} .elsewhen( stateCur === 8.U ){ //synch
|
||||
frame_info_update_en := false.B
|
||||
slave_type_num := 0.U
|
||||
slave_data_length := 0.U
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
val addrr = RegInit(0.U(10.W))
|
||||
val addrw = RegInit(0.U(10.W))
|
||||
|
||||
when( trigger_wire ){
|
||||
addrw := 0.U
|
||||
} .elsewhen( lvdsMst.io.rx_data_valid & ~isSync){
|
||||
assert( (stateCur_wire === 2.U) || (stateCur_wire === 3.U) )
|
||||
addrw := addrw + 1.U
|
||||
}
|
||||
|
||||
when( trigger_wire ){
|
||||
addrr := 0.U
|
||||
} .elsewhen( lvdsMst.io.tx_data_ready & ~isSync){
|
||||
addrr := addrr + 1.U
|
||||
}
|
||||
|
||||
mirrorDown.io.enr := (stateCur_wire === 1.U || stateCur_wire === 2.U) & ~isSync
|
||||
lvdsMst.io.tx_data_in := mirrorDown.io.datar
|
||||
mirrorDown.io.addrr := addrr
|
||||
stateCur := 9.U
|
||||
|
||||
mirrorUp.io.enw := lvdsMst.io.rx_data_valid & ~isSync
|
||||
mirrorUp.io.dataw := lvdsMst.io.rx_data_out
|
||||
mirrorUp.io.addrw := addrw
|
||||
} .elsewhen( stateCur === 9.U ){
|
||||
stateCur := 10.U
|
||||
|
||||
frame_info_update_en := true.B
|
||||
slave_type_num := Cat( "b01".U(2.W), slvNum )
|
||||
slave_data_length := ((8/8)*16-1).U
|
||||
|
||||
tx_start := false.B
|
||||
} .elsewhen( stateCur === 10.U ){ // tx start
|
||||
stateCur := 11.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
tx_start := true.B
|
||||
|
||||
} .elsewhen( stateCur === 11.U ){
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
when( RegNext(lvdsMst.io.downstream_busy, false.B) & ~lvdsMst.io.downstream_busy ){
|
||||
stateCur := 12.U
|
||||
synchCnt := synchCnt + 1.U
|
||||
}
|
||||
|
||||
} .elsewhen( stateCur === 12.U ){
|
||||
when( synchCnt === 4.U ){
|
||||
stateCur := 13.U
|
||||
} .otherwise{
|
||||
stateCur := 8.U
|
||||
}
|
||||
} .elsewhen( stateCur === 12.U ){
|
||||
statusSynch := true.B
|
||||
statusInit := true.B
|
||||
ctrlSynch := false.B
|
||||
ctrlInit := false.B
|
||||
|
||||
} .elsewhen( stateCur === 15.U ){
|
||||
|
||||
}
|
||||
.otherwise{
|
||||
assert(false.B)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
class BackBoardMst extends BackBoardMstBase with BackBoardMstFSMC with BackBoardMstLVDS
|
||||
|
||||
trait BackBoardMstLVDSTransmit{ this: BackBoardMstLVDSBase =>
|
||||
|
||||
|
||||
|
||||
val ( _, trigger ) = Counter(Range( 0,1000), ctrlTransmit )
|
||||
|
||||
|
||||
when( trigger ){ //reset
|
||||
stateCur := 0.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
slave_type_num := 0.U
|
||||
slave_data_length := 0.U
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
|
||||
} .elsewhen( stateCur === 0.U ){ //setting
|
||||
stateCur := 1.U
|
||||
|
||||
frame_info_update_en := true.B
|
||||
slave_type_num := Cat( "b10".U(2.W), slvNum )
|
||||
slave_data_length := ((8/8)*16-1).U
|
||||
|
||||
tx_start := false.B
|
||||
} .elsewhen( stateCur === 1.U ){ // tx start
|
||||
stateCur := 2.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
tx_start := true.B
|
||||
|
||||
} .elsewhen( stateCur === 2.U ){ //waiting for busy drop
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
when( RegNext(lvdsMst.io.downstream_busy, false.B) & ~lvdsMst.io.downstream_busy ){
|
||||
stateCur := 3.U
|
||||
}
|
||||
|
||||
} .elsewhen( stateCur === 3.U ){
|
||||
|
||||
} .otherwise{
|
||||
|
||||
assert(false.B)
|
||||
}
|
||||
|
||||
val addrr = RegInit(0.U(10.W))
|
||||
val addrw = RegInit(0.U(10.W))
|
||||
|
||||
when( trigger ){
|
||||
addrw := 0.U
|
||||
} .elsewhen( lvdsMst.io.rx_data_valid & ~isSync){
|
||||
assert( (stateCur === 2.U) || (stateCur === 3.U) )
|
||||
addrw := addrw + 1.U
|
||||
}
|
||||
|
||||
when( trigger ){
|
||||
addrr := 0.U
|
||||
} .elsewhen( lvdsMst.io.tx_data_ready & ~isSync){
|
||||
addrr := addrr + 1.U
|
||||
}
|
||||
|
||||
mirrorDown.io.enr := (stateCur === 1.U || stateCur === 2.U) & ~isSync
|
||||
lvdsMst.io.tx_data_in := mirrorDown.io.datar
|
||||
mirrorDown.io.addrr := addrr
|
||||
|
||||
mirrorUp.io.enw := lvdsMst.io.rx_data_valid & ~isSync
|
||||
mirrorUp.io.dataw := lvdsMst.io.rx_data_out
|
||||
mirrorUp.io.addrw := addrw
|
||||
|
||||
}
|
||||
|
||||
trait BackBoardMstLVDSError{ this: BackBoardMstLVDSBase =>
|
||||
when( lvdsMst.io.closed_loop_err ){
|
||||
slvOffLine := lvdsMst.io.link_err_location(5,0)
|
||||
statuslinkErr := true.B
|
||||
statusSynch := false.B
|
||||
statusInit := false.B
|
||||
}
|
||||
|
||||
when( lvdsMst.io.upstream_cdr_err ){
|
||||
statusCDRErr := true.B
|
||||
ctrlTransmit := false.B
|
||||
}
|
||||
|
||||
when( lvdsMst.io.upstream_crc_valid & upstream_crc_err ){
|
||||
statusCRCErr := true.B
|
||||
ctrlTransmit := false.B
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BackBoardMst extends BackBoardMstLVDSBase
|
||||
with BackBoardMstLVDSInitialization
|
||||
with BackBoardMstLVDSTransmit
|
||||
with BackBoardMstLVDSError
|
||||
|
||||
Reference in New Issue
Block a user