删除其它项目设计文件
This commit is contained in:
@@ -1,647 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
|
||||
|
||||
class FSMC_Port_Bundle extends Bundle{
|
||||
|
||||
val ADIn = Input(UInt(16.W))
|
||||
val ADOut = Output(UInt(16.W))
|
||||
val ADOEn = Output(Bool())
|
||||
val csn = Input(Bool())
|
||||
val rdn = Input(Bool())
|
||||
val wrn = Input(Bool())
|
||||
val advn = Input(Bool())
|
||||
}
|
||||
|
||||
class LVDS_MST_Bundle extends Bundle{
|
||||
val frame_info_update_en = Output(Bool())
|
||||
val slave_type_num = Output(UInt(8.W))
|
||||
val slave_data_length = Output(UInt(8.W))
|
||||
val tx_start = Output(Bool())
|
||||
|
||||
val slave_link_num_valid = Input(Bool())
|
||||
val slave_link_num = Input(UInt(7.W))
|
||||
|
||||
val downstream_busy = Input(Bool())
|
||||
val upstream_crc_valid = Input(Bool())
|
||||
|
||||
val closed_loop_err = Input(Bool())
|
||||
val link_err_location = Input(UInt(7.W))
|
||||
|
||||
val upstream_cdr_err = Input(Bool())
|
||||
val upstream_crc_err = Input(Bool())
|
||||
|
||||
val tx_data_ready = Input(Bool())
|
||||
val tx_data_in = Output(UInt(8.W))
|
||||
val rx_data_valid = Input(Bool())
|
||||
val rx_data_out = Input(UInt(8.W))
|
||||
}
|
||||
|
||||
|
||||
|
||||
class BackBoardMstIO extends Bundle{
|
||||
val FSMC = new FSMC_Port_Bundle
|
||||
|
||||
val oser_pclk = Input(Bool()) //10M
|
||||
val oser_fclk = Input(Bool()) //50M
|
||||
val ides_pclk = Input(Bool()) //100M
|
||||
val ides_fclk = Input(Bool()) //400M
|
||||
|
||||
|
||||
val interrupt = Output(Bool())
|
||||
|
||||
val testIO = Input(Bool())
|
||||
|
||||
val lvdsMst = new LVDS_MST_Bundle
|
||||
|
||||
}
|
||||
|
||||
class BackBoardMstBase extends Module{ //10M
|
||||
|
||||
def OPERATORADDR = 0.U
|
||||
def STATUSINITADDR = 1.U
|
||||
def STATUSSYNCHADDR = 2.U
|
||||
def STATUSTRANSADDR = 3.U
|
||||
def STATUSUNICASTADDR = 4.U
|
||||
def SLVNUMADDR = 5.U
|
||||
def SLVDATALENADDR = 6.U
|
||||
def SLVLINKNUMADDR = 7.U
|
||||
def LINKERRLOCADDR = 8.U
|
||||
def STATUSLINKERRADDR = 9.U
|
||||
def STATUSCDRERRADDR = 10.U
|
||||
def STATUSCRCERRADDR = 11.U
|
||||
|
||||
|
||||
val io: BackBoardMstIO = IO(new BackBoardMstIO)
|
||||
|
||||
val mirrorDown = Module(new MirrorSRAMDP())
|
||||
val mirrorUp = Module(new MirrorSRAMDP())
|
||||
val mirrorReg = Module(new MirrorSRAMDP())
|
||||
|
||||
mirrorReg.io.addrB := DontCare
|
||||
mirrorReg.io.datawB := DontCare
|
||||
mirrorReg.io.enwB := false.B
|
||||
mirrorReg.io.enrB := false.B
|
||||
|
||||
assert( ~(mirrorReg.io.enwA & mirrorReg.io.enrA) )
|
||||
assert( ~(mirrorReg.io.enwB & mirrorReg.io.enrB) )
|
||||
|
||||
val ctrlTransmit = RegInit( false.B )
|
||||
val ctrlUnicast = RegInit( false.B )
|
||||
val ctrlSynch = RegInit( false.B )
|
||||
val ctrlInit = RegInit( false.B )
|
||||
|
||||
val slvNum = RegInit(0.U(6.W))
|
||||
val interrupt = RegInit(false.B); io.interrupt := interrupt
|
||||
val slaveDataLength = Reg(UInt(8.W)) //(8/8)*32-1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
mirrorDown.io.clockA := io.ides_pclk.asBool //100M
|
||||
mirrorDown.io.clockB := io.oser_pclk.asBool
|
||||
|
||||
mirrorUp.io.clockA := io.ides_pclk.asBool //100M
|
||||
mirrorUp.io.clockB := io.oser_pclk.asBool
|
||||
|
||||
mirrorReg.io.clockA := io.ides_pclk.asBool //100M
|
||||
mirrorReg.io.clockB := io.oser_pclk.asBool //10M
|
||||
|
||||
when(interrupt === true.B){
|
||||
interrupt := false.B
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
trait BackBoardMstFSMC{ this: BackBoardMstBase =>
|
||||
|
||||
withClockAndReset( io.ides_pclk.asClock, reset ){//100M
|
||||
|
||||
io.FSMC.ADOEn := ~io.FSMC.rdn & ~io.FSMC.csn & io.FSMC.advn
|
||||
|
||||
val latchAddr = RegEnable( io.FSMC.ADIn, ~io.FSMC.advn & ~io.FSMC.csn)
|
||||
|
||||
val isAccessSRAM = ~latchAddr.extract(11)
|
||||
val isAccessReg = latchAddr.extract(11)
|
||||
val isAccessDown = ~latchAddr.extract(10)
|
||||
val activeAddr = latchAddr(9,0)
|
||||
|
||||
mirrorDown.io.addrA := activeAddr
|
||||
mirrorDown.io.datawA := io.FSMC.ADIn
|
||||
mirrorDown.io.enwA := isAccessSRAM & ~io.FSMC.csn & ~io.FSMC.wrn & isAccessDown
|
||||
mirrorDown.io.enrA := isAccessSRAM & ~io.FSMC.csn & ~io.FSMC.rdn & isAccessDown
|
||||
|
||||
mirrorUp.io.addrA := activeAddr
|
||||
mirrorUp.io.datawA := io.FSMC.ADIn
|
||||
mirrorUp.io.enwA := isAccessSRAM & ~io.FSMC.csn & ~io.FSMC.wrn & ~isAccessDown
|
||||
mirrorUp.io.enrA := isAccessSRAM & ~io.FSMC.csn & ~io.FSMC.rdn & ~isAccessDown
|
||||
|
||||
mirrorReg.io.addrA := activeAddr
|
||||
mirrorReg.io.datawA := io.FSMC.ADIn
|
||||
mirrorReg.io.enwA := isAccessReg & ~io.FSMC.csn & ~io.FSMC.wrn
|
||||
mirrorReg.io.enrA := isAccessReg & ~io.FSMC.csn & ~io.FSMC.rdn
|
||||
|
||||
io.FSMC.ADOut := Mux( isAccessReg, mirrorReg.io.datarA, Mux( isAccessDown, mirrorDown.io.datarA, mirrorUp.io.datarA) )
|
||||
|
||||
|
||||
}
|
||||
|
||||
//10M
|
||||
val testIOShift = ShiftRegisters(io.testIO, 3, false.B, true.B)
|
||||
when(~testIOShift(0) & io.testIO){
|
||||
|
||||
mirrorReg.io.addrB := OPERATORADDR
|
||||
mirrorReg.io.enrB := true.B
|
||||
} .elsewhen( ~testIOShift(1) & testIOShift(0)){
|
||||
when( mirrorReg.io.datarB === 0.U ){
|
||||
ctrlInit := true.B
|
||||
}
|
||||
|
||||
when( mirrorReg.io.datarB === 1.U ){
|
||||
ctrlSynch := true.B
|
||||
}
|
||||
|
||||
when( mirrorReg.io.datarB === 5.U ){
|
||||
ctrlTransmit := true.B
|
||||
}
|
||||
|
||||
when( mirrorReg.io.datarB === 6.U ){
|
||||
ctrlUnicast := true.B
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 tx_start = RegInit(false.B)
|
||||
|
||||
io.lvdsMst.frame_info_update_en := frame_info_update_en
|
||||
io.lvdsMst.slave_type_num := slave_type_num
|
||||
io.lvdsMst.slave_data_length := slaveDataLength
|
||||
io.lvdsMst.tx_start := tx_start
|
||||
|
||||
val stateCur = RegInit(15.U(4.W))
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait BackBoardMstLVDSInit{ this: BackBoardMstLVDSBase =>
|
||||
|
||||
val isInitStart = ~RegNext(ctrlInit, false.B) & ctrlInit
|
||||
val timeoutCnt = Reg(UInt(13.W))
|
||||
|
||||
when(ctrlInit){
|
||||
when( isInitStart ){
|
||||
|
||||
stateCur := 0.U
|
||||
frame_info_update_en := false.B
|
||||
slave_type_num := 0.U
|
||||
tx_start := false.B
|
||||
|
||||
} .elsewhen( stateCur === 0.U ){
|
||||
stateCur := 1.U
|
||||
|
||||
// write statusInit
|
||||
mirrorReg.io.addrB := STATUSINITADDR
|
||||
mirrorReg.io.datawB := 0.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
} .elsewhen( stateCur === 1.U ){
|
||||
stateCur := 2.U
|
||||
|
||||
//req slvnum
|
||||
mirrorReg.io.addrB := SLVNUMADDR
|
||||
mirrorReg.io.enrB := true.B
|
||||
|
||||
} .elsewhen( stateCur === 2.U ){
|
||||
stateCur := 3.U
|
||||
|
||||
//lock slvNum
|
||||
slvNum := mirrorReg.io.datarB
|
||||
|
||||
//req slaveDataLength
|
||||
mirrorReg.io.addrB := SLVDATALENADDR
|
||||
mirrorReg.io.enrB := true.B
|
||||
|
||||
}
|
||||
.elsewhen( stateCur === 3.U ){
|
||||
stateCur := 4.U
|
||||
|
||||
//lock slaveDataLength
|
||||
slaveDataLength := mirrorReg.io.datarB
|
||||
|
||||
frame_info_update_en := true.B
|
||||
slave_type_num := Cat( "b00".U(2.W), slvNum )
|
||||
|
||||
tx_start := false.B
|
||||
} .elsewhen( stateCur === 4.U ){ // tx start
|
||||
stateCur := 5.U
|
||||
timeoutCnt := 0.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
tx_start := true.B
|
||||
|
||||
} .elsewhen( stateCur === 5.U ){
|
||||
tx_start := false.B
|
||||
timeoutCnt := timeoutCnt + 1.U
|
||||
|
||||
when( io.lvdsMst.slave_link_num_valid ){
|
||||
stateCur := 6.U
|
||||
|
||||
//linkNum
|
||||
mirrorReg.io.addrB := SLVLINKNUMADDR
|
||||
mirrorReg.io.datawB := io.lvdsMst.slave_link_num
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
}
|
||||
|
||||
when( timeoutCnt === 6000.U ){
|
||||
stateCur := 6.U
|
||||
|
||||
//linkNum
|
||||
mirrorReg.io.addrB := SLVLINKNUMADDR
|
||||
mirrorReg.io.datawB := 0.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
} .elsewhen( stateCur === 6.U ){
|
||||
stateCur := 7.U
|
||||
|
||||
//statusInit
|
||||
mirrorReg.io.addrB := STATUSINITADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
ctrlInit := false.B
|
||||
ctrlSynch := false.B
|
||||
ctrlTransmit := false.B
|
||||
ctrlUnicast := false.B
|
||||
interrupt := true.B
|
||||
|
||||
} .elsewhen( stateCur === 7.U ){
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait BackBoardMstLVDSSync{ this: BackBoardMstLVDSBase =>
|
||||
val isSyncStart = ~RegNext( ctrlSynch, false.B) & ctrlSynch
|
||||
|
||||
when( ctrlSynch ){
|
||||
when( isSyncStart ){
|
||||
stateCur := 0.U
|
||||
frame_info_update_en := false.B
|
||||
slave_type_num := 0.U
|
||||
tx_start := false.B
|
||||
|
||||
} .elsewhen( stateCur === 0.U ){ //statusSynch
|
||||
stateCur := 1.U
|
||||
|
||||
mirrorReg.io.addrB := STATUSSYNCHADDR
|
||||
mirrorReg.io.datawB := 0.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
} .elsewhen( stateCur === 1.U ){
|
||||
stateCur := 2.U
|
||||
|
||||
//req slvnum
|
||||
mirrorReg.io.addrB := SLVNUMADDR
|
||||
mirrorReg.io.enrB := true.B
|
||||
|
||||
|
||||
} .elsewhen( stateCur === 2.U ){ //slaveDataLength
|
||||
stateCur := 3.U
|
||||
|
||||
//lock slvNum
|
||||
slvNum := mirrorReg.io.datarB
|
||||
|
||||
//slaveDataLength
|
||||
mirrorReg.io.addrB := SLVDATALENADDR
|
||||
mirrorReg.io.enrB := true.B
|
||||
|
||||
|
||||
} .elsewhen( stateCur === 3.U ){
|
||||
stateCur := 4.U
|
||||
|
||||
//lock slaveDataLength
|
||||
slaveDataLength := mirrorReg.io.datarB
|
||||
|
||||
frame_info_update_en := true.B
|
||||
slave_type_num := Cat( "b01".U(2.W), slvNum )
|
||||
|
||||
tx_start := false.B
|
||||
} .elsewhen( stateCur === 4.U ){ // tx start
|
||||
stateCur := 5.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
tx_start := true.B
|
||||
|
||||
} .elsewhen( stateCur === 5.U ){
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
when( RegNext(io.lvdsMst.downstream_busy, false.B) & ~io.lvdsMst.downstream_busy ){
|
||||
stateCur := 6.U
|
||||
|
||||
//statusSync
|
||||
mirrorReg.io.addrB := STATUSSYNCHADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
ctrlSynch := false.B
|
||||
interrupt := true.B
|
||||
}
|
||||
|
||||
} .otherwise{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait BackBoardMstLVDSTransmit{ this: BackBoardMstLVDSBase =>
|
||||
|
||||
val isTransStart = ctrlTransmit & ~RegNext(ctrlTransmit, false.B)
|
||||
|
||||
when(ctrlTransmit){
|
||||
when( isTransStart ){ //reset
|
||||
stateCur := 0.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
slave_type_num := 0.U
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
|
||||
} .elsewhen( stateCur === 0.U ){ //statusTransmit
|
||||
stateCur := 1.U
|
||||
|
||||
mirrorReg.io.addrB := STATUSTRANSADDR
|
||||
mirrorReg.io.datawB := 0.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
} .elsewhen( stateCur === 1.U ){ //slvnum
|
||||
stateCur := 2.U
|
||||
|
||||
mirrorReg.io.addrB := SLVNUMADDR
|
||||
mirrorReg.io.enrB := true.B
|
||||
|
||||
} .elsewhen( stateCur === 2.U ){ //slaveDataLength
|
||||
stateCur := 3.U
|
||||
|
||||
//lock slvNum
|
||||
slvNum := mirrorReg.io.datarB
|
||||
|
||||
mirrorReg.io.addrB := SLVDATALENADDR
|
||||
mirrorReg.io.enrB := true.B
|
||||
|
||||
} .elsewhen( stateCur === 3.U ){ //setting
|
||||
stateCur := 4.U
|
||||
|
||||
//lock slaveDataLength
|
||||
slaveDataLength := mirrorReg.io.datarB
|
||||
|
||||
frame_info_update_en := true.B
|
||||
slave_type_num := Cat( "b10".U(2.W), slvNum )
|
||||
|
||||
tx_start := false.B
|
||||
} .elsewhen( stateCur === 4.U ){ // tx start
|
||||
stateCur := 5.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
tx_start := true.B
|
||||
|
||||
} .elsewhen( stateCur === 5.U ){ //waiting for busy drop
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
when( RegNext(io.lvdsMst.downstream_busy, false.B) & ~io.lvdsMst.downstream_busy ){
|
||||
stateCur := 6.U
|
||||
}
|
||||
|
||||
} .elsewhen( stateCur === 6.U ){
|
||||
when( io.lvdsMst.upstream_crc_valid ){
|
||||
stateCur := 7.U
|
||||
|
||||
when( io.lvdsMst.upstream_crc_err ){
|
||||
mirrorReg.io.addrB := STATUSCRCERRADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
}
|
||||
}
|
||||
} .elsewhen( stateCur === 7.U ){
|
||||
stateCur := 8.U
|
||||
|
||||
//statusTransmit
|
||||
mirrorReg.io.addrB := STATUSTRANSADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
ctrlTransmit := false.B
|
||||
interrupt := true.B
|
||||
}.elsewhen( stateCur === 8.U ){
|
||||
|
||||
} .otherwise{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait BackBoardMstLVDSUnicast{ this: BackBoardMstLVDSBase =>
|
||||
|
||||
val isUnicast = ctrlUnicast & ~RegNext(ctrlUnicast, false.B)
|
||||
|
||||
when(ctrlUnicast){
|
||||
when( isUnicast ){ //reset
|
||||
stateCur := 0.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
slave_type_num := 0.U
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
|
||||
} .elsewhen( stateCur === 0.U ){ //statusUnicast
|
||||
stateCur := 1.U
|
||||
|
||||
mirrorReg.io.addrB := STATUSUNICASTADDR
|
||||
mirrorReg.io.datawB := 0.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
} .elsewhen( stateCur === 1.U ){ //slvnum
|
||||
stateCur := 2.U
|
||||
|
||||
mirrorReg.io.addrB := SLVNUMADDR
|
||||
mirrorReg.io.enrB := true.B
|
||||
|
||||
} .elsewhen( stateCur === 2.U ){ //slaveDataLength
|
||||
stateCur := 3.U
|
||||
|
||||
//lock slvNum
|
||||
slvNum := mirrorReg.io.datarB
|
||||
|
||||
mirrorReg.io.addrB := SLVDATALENADDR
|
||||
mirrorReg.io.enrB := true.B
|
||||
|
||||
} .elsewhen( stateCur === 3.U ){ //setting
|
||||
stateCur := 4.U
|
||||
|
||||
//lock slaveDataLength
|
||||
slaveDataLength := mirrorReg.io.datarB
|
||||
|
||||
frame_info_update_en := true.B
|
||||
slave_type_num := Cat( "b11".U(2.W), slvNum )
|
||||
|
||||
tx_start := false.B
|
||||
} .elsewhen( stateCur === 4.U ){ // tx start
|
||||
stateCur := 5.U
|
||||
|
||||
frame_info_update_en := false.B
|
||||
tx_start := true.B
|
||||
|
||||
} .elsewhen( stateCur === 5.U ){ //waiting for busy drop
|
||||
|
||||
tx_start := false.B
|
||||
|
||||
when( RegNext(io.lvdsMst.downstream_busy, false.B) & ~io.lvdsMst.downstream_busy ){
|
||||
stateCur := 6.U
|
||||
}
|
||||
|
||||
} .elsewhen( stateCur === 6.U ){
|
||||
when( io.lvdsMst.upstream_crc_valid ){
|
||||
stateCur := 7.U
|
||||
|
||||
when( io.lvdsMst.upstream_crc_err ){
|
||||
mirrorReg.io.addrB := STATUSCRCERRADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
}
|
||||
|
||||
}
|
||||
} .elsewhen( stateCur === 7.U ){
|
||||
stateCur := 8.U
|
||||
|
||||
//statusUnicast
|
||||
mirrorReg.io.addrB := STATUSUNICASTADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
ctrlUnicast := false.B
|
||||
interrupt := true.B
|
||||
|
||||
} .elsewhen( stateCur === 8.U ){
|
||||
|
||||
} .otherwise{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait BackBoardMstLVDSError{ this: BackBoardMstLVDSBase =>
|
||||
val shiftClosedLoopErr = ShiftRegisters( io.lvdsMst.closed_loop_err, 6, false.B, true.B )
|
||||
when( ~shiftClosedLoopErr(0) & io.lvdsMst.closed_loop_err ){
|
||||
mirrorReg.io.addrB := LINKERRLOCADDR
|
||||
mirrorReg.io.datawB := io.lvdsMst.link_err_location(5,0)
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
} .elsewhen( ~shiftClosedLoopErr(1) & shiftClosedLoopErr(0) ){
|
||||
mirrorReg.io.addrB := STATUSLINKERRADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
} .elsewhen( ~shiftClosedLoopErr(2) & shiftClosedLoopErr(1) ){
|
||||
mirrorReg.io.addrB := STATUSSYNCHADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
ctrlSynch := false.B
|
||||
|
||||
} .elsewhen( ~shiftClosedLoopErr(3) & shiftClosedLoopErr(2) ){
|
||||
mirrorReg.io.addrB := STATUSTRANSADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
ctrlTransmit := false.B
|
||||
|
||||
} .elsewhen( ~shiftClosedLoopErr(4) & shiftClosedLoopErr(3) ){
|
||||
mirrorReg.io.addrB := STATUSUNICASTADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
|
||||
ctrlUnicast := false.B
|
||||
} .elsewhen( ~shiftClosedLoopErr(5) & shiftClosedLoopErr(4) ){
|
||||
interrupt := true.B
|
||||
}
|
||||
|
||||
|
||||
|
||||
val shiftCDRErr = ShiftRegisters( io.lvdsMst.upstream_cdr_err, 2, false.B, true.B )
|
||||
when( ~shiftCDRErr(0) & io.lvdsMst.upstream_cdr_err ){
|
||||
mirrorReg.io.addrB := STATUSCDRERRADDR
|
||||
mirrorReg.io.datawB := 1.U
|
||||
mirrorReg.io.enwB := true.B
|
||||
interrupt := true.B
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BackBoardMst extends BackBoardMstLVDSBase
|
||||
with BackBoardMstLVDSInit
|
||||
with BackBoardMstLVDSSync
|
||||
with BackBoardMstLVDSTransmit
|
||||
with BackBoardMstLVDSUnicast
|
||||
with BackBoardMstLVDSError{
|
||||
|
||||
val addrr = RegInit(0.U(11.W))
|
||||
val addrw = RegInit(0.U(11.W))
|
||||
|
||||
when( isTransStart | isUnicast ){
|
||||
addrw := 0.U
|
||||
} .elsewhen( io.lvdsMst.rx_data_valid & (ctrlTransmit | ctrlUnicast) ){
|
||||
assert( (stateCur === 5.U) || (stateCur === 6.U) )
|
||||
addrw := addrw + 1.U
|
||||
}
|
||||
|
||||
when( isTransStart | isUnicast ){
|
||||
addrr := 0.U
|
||||
} .elsewhen( io.lvdsMst.tx_data_ready & (ctrlTransmit | ctrlUnicast) ){
|
||||
addrr := addrr + 1.U
|
||||
}
|
||||
|
||||
mirrorDown.io.enwB := false.B
|
||||
mirrorDown.io.datawB := 0.U
|
||||
mirrorDown.io.enrB := (stateCur === 4.U || stateCur === 5.U) & (ctrlTransmit | ctrlUnicast)
|
||||
io.lvdsMst.tx_data_in := Mux( addrr.extract(0), mirrorDown.io.datarB(7,0), mirrorDown.io.datarB(15,8) )
|
||||
mirrorDown.io.addrB := addrr >> 1
|
||||
|
||||
|
||||
val rxData_lsb = RegEnable( io.lvdsMst.rx_data_out, io.lvdsMst.rx_data_valid & (ctrlTransmit | ctrlUnicast) & ~addrw.extract(0) )
|
||||
mirrorUp.io.enrB := false.B
|
||||
mirrorUp.io.enwB := io.lvdsMst.rx_data_valid & (ctrlTransmit | ctrlUnicast) & addrw.extract(0)
|
||||
mirrorUp.io.datawB := Cat( io.lvdsMst.rx_data_out, rxData_lsb )
|
||||
mirrorUp.io.addrB := addrw >> 1
|
||||
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
class LVDS_SLV_Bundle extends Bundle{
|
||||
val downstream_rx_data_valid = Input(Bool())
|
||||
val downstream_rx_data_out = Input(UInt(8.W))
|
||||
val downstream_rx_crc_valid = Input(Bool())
|
||||
val downstream_rx_crc_err = Input(Bool())
|
||||
val upstream_tx_data_in = Output(UInt(8.W))
|
||||
val upstream_tx_data_ready = Input(Bool())
|
||||
|
||||
val downstream_rx_cdr_err = Input(Bool())
|
||||
val upstream_rx_cdr_err = Input(Bool())
|
||||
}
|
||||
|
||||
|
||||
class BackBoardSlvIO extends Bundle{
|
||||
|
||||
val isOnline = Output(Bool())
|
||||
val isLast = Input(Bool())
|
||||
|
||||
val DCIn = Input(Bool())
|
||||
|
||||
val lvdsSlv = new LVDS_SLV_Bundle
|
||||
}
|
||||
|
||||
|
||||
abstract class BackBoardSlvBase extends Module{
|
||||
val io: BackBoardSlvIO = IO(new BackBoardSlvIO)
|
||||
|
||||
val downRegTemp = RegInit(VecInit( Seq(15.U(8.W)) ++ Seq.fill(31){0.U(8.W)} ))
|
||||
val upReg = WireDefault(VecInit((0 until 32).map{i => 0.U(8.W)}))
|
||||
}
|
||||
|
||||
|
||||
trait BackBoardSlvDown{ this: BackBoardSlvBase =>
|
||||
|
||||
|
||||
val downCnt = Reg(UInt(6.W))
|
||||
|
||||
|
||||
when( io.lvdsSlv.downstream_rx_data_valid ){
|
||||
downRegTemp(downCnt) := io.lvdsSlv.downstream_rx_data_out
|
||||
downCnt := downCnt + 1.U
|
||||
} .otherwise{
|
||||
downCnt := 0.U
|
||||
}
|
||||
|
||||
val isCrcPass = io.lvdsSlv.downstream_rx_crc_valid & ~io.lvdsSlv.downstream_rx_crc_err
|
||||
|
||||
// when( io.lvdsSlv.downstream_rx_crc_valid ){
|
||||
// when( ~io.lvdsSlv.downstream_rx_crc_err ){
|
||||
// for( i <- 1 until 32 ) {
|
||||
// downReg(i) := downRegTemp(i)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// when( RegNext(io.lvdsSlv.downstream_rx_data_valid,false.B) & ~io.lvdsSlv.downstream_rx_data_valid ){
|
||||
// for( i <- 1 until 32 ) {
|
||||
// downReg(i) := downRegTemp(i)
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
trait BackBoardSlvUp{ this: BackBoardSlvBase =>
|
||||
|
||||
val upCnt = Reg(UInt(6.W))
|
||||
|
||||
io.lvdsSlv.upstream_tx_data_in := upReg(upCnt)
|
||||
|
||||
when( io.lvdsSlv.upstream_tx_data_ready ){
|
||||
when( ~RegNext(io.lvdsSlv.upstream_tx_data_ready, false.B) ){
|
||||
upCnt := 0.U
|
||||
} .otherwise{
|
||||
upCnt := upCnt + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
trait BackBoardSlvIn16 { this: BackBoardSlvLocal =>
|
||||
|
||||
val inPin = Wire(UInt(16.W))
|
||||
|
||||
|
||||
val flitCnt = RegInit(MixedVecInit(Seq( false.B, 0.U(4.W), false.B, false.B, false.B, false.B, false.B, false.B, false.B) ))
|
||||
val flitTrigger = Wire(Vec(9, Bool()))
|
||||
val digitalFilter = for( i <- 0 until 2 ) yield { RegInit( 2.U(8.W) ) }
|
||||
val digitalIn = for( i <- 0 until 2 ) yield { Reg( Vec(8, Bool()) ) }
|
||||
|
||||
|
||||
flitTrigger(0) := ~RegNext(flitTrigger(0))
|
||||
|
||||
flitTrigger(1) := flitCnt(1) === 15.U
|
||||
when( ~RegNext(usTrigger) & usTrigger ){
|
||||
flitCnt(1) := flitCnt(1) + 1.U
|
||||
}
|
||||
|
||||
flitTrigger(2) := flitCnt(2)
|
||||
when( ~RegNext(flitTrigger(1)) & flitTrigger(1) ){
|
||||
flitCnt(2) := ~flitCnt(2)
|
||||
}
|
||||
|
||||
flitTrigger(3) := flitCnt(3)
|
||||
when( ~RegNext(flitTrigger(2)) & flitTrigger(2) ){
|
||||
flitCnt(3) := ~flitCnt(3)
|
||||
}
|
||||
|
||||
flitTrigger(4) := flitCnt(4)
|
||||
when( ~RegNext(flitTrigger(3)) & flitTrigger(3) ){
|
||||
flitCnt(4) := ~flitCnt(4)
|
||||
}
|
||||
|
||||
flitTrigger(5) := flitCnt(5)
|
||||
when( ~RegNext(flitTrigger(4)) & flitTrigger(4) ){
|
||||
flitCnt(5) := ~flitCnt(5)
|
||||
}
|
||||
|
||||
flitTrigger(6) := flitCnt(6)
|
||||
when( ~RegNext(flitTrigger(5)) & flitTrigger(5) ){
|
||||
flitCnt(6) := ~flitCnt(6)
|
||||
}
|
||||
|
||||
flitTrigger(7) := flitCnt(7)
|
||||
when( ~RegNext(flitTrigger(6)) & flitTrigger(6) ){
|
||||
flitCnt(7) := ~flitCnt(7)
|
||||
}
|
||||
|
||||
flitTrigger(8) := flitCnt(8)
|
||||
when( ~RegNext(flitTrigger(7)) & flitTrigger(7) ){
|
||||
flitCnt(8) := ~flitCnt(8)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for( i <- 0 until 8 ) {
|
||||
for( j <- 0 until 2 ) {
|
||||
val flitter = RegInit(VecInit( Seq.fill(16){false.B}))
|
||||
val flitHi = RegInit(0.U((log2Ceil(16)).W))
|
||||
val shiftIn = RegNext( inPin(i+8*j) )
|
||||
|
||||
val sample =
|
||||
Mux( digitalFilter(j) === 1.U, ~RegNext(flitTrigger(1)) & flitTrigger(1),
|
||||
Mux(digitalFilter(j) === 2.U, ~RegNext(flitTrigger(2)) & flitTrigger(2),
|
||||
Mux(digitalFilter(j) === 3.U, ~RegNext(flitTrigger(3)) & flitTrigger(3),
|
||||
Mux(digitalFilter(j) === 4.U, ~RegNext(flitTrigger(4)) & flitTrigger(4),
|
||||
Mux(digitalFilter(j) === 5.U, ~RegNext(flitTrigger(5)) & flitTrigger(5),
|
||||
Mux(digitalFilter(j) === 6.U, ~RegNext(flitTrigger(6)) & flitTrigger(6),
|
||||
Mux(digitalFilter(j) === 7.U, ~RegNext(flitTrigger(7)) & flitTrigger(7),
|
||||
Mux(digitalFilter(j) === 8.U, ~RegNext(flitTrigger(8)) & flitTrigger(8), true.B
|
||||
))))))))
|
||||
|
||||
|
||||
when( sample ){
|
||||
flitter(0) := shiftIn
|
||||
(1 until 16).map{ k =>
|
||||
flitter(k) := flitter(k-1)
|
||||
}
|
||||
|
||||
when( ~flitter(15) & flitter(0) ){
|
||||
flitHi := flitHi + 1.U
|
||||
} .elsewhen( flitter(15) & ~flitter(0) ){
|
||||
flitHi := flitHi - 1.U
|
||||
}
|
||||
|
||||
when( flitHi === 12.U ){
|
||||
digitalIn(j)(i) := true.B
|
||||
} .elsewhen( flitHi === 3.U ){
|
||||
digitalIn(j)(i) := false.B
|
||||
}
|
||||
|
||||
// val fliterCnt = WireDefault( VecInit( (1 until 16).map{ k => flitter(k) }) )
|
||||
|
||||
// assert( flitHi <= 15.U )
|
||||
// assert( fliterCnt.count( (k:Bool) => k === true.B ) === flitHi )
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class DIn16 extends BackBoardSlvLocal
|
||||
with BackBoardSlvStatusPR
|
||||
with BackBoardSlvIn16{
|
||||
|
||||
val in = IO(Input(UInt(16.W)))
|
||||
|
||||
inPin := in
|
||||
|
||||
|
||||
when( isCrcPass & downRegTemp(0)(3,0) === 0.U ){
|
||||
digitalFilter(0) := downRegTemp(4)
|
||||
digitalFilter(1) := downRegTemp(5)
|
||||
}
|
||||
|
||||
val digitalInSync = for( i <- 0 until 2 ) yield { RegEnable( Cat( digitalIn(i).reverse ), isUpdate ) }
|
||||
|
||||
when( statusPage === 0.U ){
|
||||
upReg(2) := digitalInSync(0)
|
||||
upReg(3) := digitalInSync(1)
|
||||
upReg(4) := digitalFilter(0)
|
||||
upReg(5) := digitalFilter(1)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
trait BackBoardSlvOut16{ this: BackBoardSlvLocal =>
|
||||
|
||||
val outRegSync = Wire(UInt(16.W))
|
||||
|
||||
val mthodReg = RegInit(0.U(16.W))
|
||||
val valueReg = RegInit(0.U(16.W))
|
||||
|
||||
val outPin = Wire(UInt(16.W))
|
||||
|
||||
outPin :=
|
||||
Mux(statusPR === 3.U, outRegSync, (mthodReg & valueReg) | (~mthodReg & outRegSync))
|
||||
|
||||
}
|
||||
|
||||
trait DoutInspect{ this: BackBoardSlvLocal =>
|
||||
val flt = IO(Input(Vec(2, Bool())))
|
||||
val v24Det = IO(Input(Bool()))
|
||||
val LED_ERR = IO(Output(Bool()))
|
||||
|
||||
LED_ERR := ~RegNext(~v24Det)
|
||||
|
||||
when( statusPage === 0.U ){
|
||||
upReg(2) := Cat( 0.U(7.W), RegNext(~v24Det) )
|
||||
upReg(3) := 0.U
|
||||
upReg(4) := Cat( 0.U(7.W), RegNext(~flt(0)) )
|
||||
upReg(5) := 0.U
|
||||
upReg(6) := Cat( 0.U(7.W), RegNext(~flt(1)) )
|
||||
upReg(7) := 0.U
|
||||
}
|
||||
}
|
||||
|
||||
trait DoutInspect_Plus{ this: BackBoardSlvLocal =>
|
||||
val flashCounter: UInt
|
||||
|
||||
val v24Det = IO(Input(Bool()))
|
||||
val LED_ERR = IO(Output(Bool()))
|
||||
|
||||
val fin_cur = IO(Input(UInt(4.W)))
|
||||
val fin_sel = IO(Output(UInt(3.W)))
|
||||
val fin_clk = IO(Output(Bool()))
|
||||
val fin_vol = IO(Input(UInt(3.W)))
|
||||
|
||||
val inspectCurr = for( i <- 0 until 4 ) yield { RegInit(0.U(8.W)) }
|
||||
val finSelReg = RegInit(0.U(3.W)); fin_sel := finSelReg
|
||||
val finClkReg = RegInit(false.B); fin_clk := finClkReg
|
||||
|
||||
|
||||
when(flashCounter(2,0).andR){
|
||||
finClkReg := ~finClkReg
|
||||
}
|
||||
|
||||
when( flashCounter(2,0).andR & finClkReg ){
|
||||
finSelReg := finSelReg + 1.U
|
||||
|
||||
inspectCurr(0) := ( inspectCurr(0) & ~( 1.U(8.W) << finSelReg) ) | ( fin_cur.extract(0) << finSelReg )
|
||||
inspectCurr(1) := ( inspectCurr(1) & ~( 1.U(8.W) << finSelReg) ) | ( fin_cur.extract(1) << finSelReg )
|
||||
inspectCurr(2) := ( inspectCurr(2) & ~( 1.U(8.W) << finSelReg) ) | ( fin_cur.extract(2) << finSelReg )
|
||||
inspectCurr(3) := ( inspectCurr(3) & ~( 1.U(8.W) << finSelReg) ) | ( fin_cur.extract(3) << finSelReg )
|
||||
}
|
||||
|
||||
LED_ERR := ~( RegNext(~v24Det) | ( inspectCurr.map{ (isp: UInt) => (isp =/= 0.U) }.reduce(_|_) ) | ( RegNext(fin_vol) =/= 0.U ) )
|
||||
|
||||
when( statusPage === 0.U ){
|
||||
upReg(2) := Cat( 0.U(4.W), RegNext(fin_vol), RegNext(~v24Det) )
|
||||
upReg(3) := 0.U
|
||||
upReg(4) := inspectCurr(0)
|
||||
upReg(5) := inspectCurr(1)
|
||||
upReg(6) := inspectCurr(2)
|
||||
upReg(7) := inspectCurr(3)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
abstract class DOut16 extends BackBoardSlvLocal
|
||||
with BackBoardSlvStatusPR
|
||||
with BackBoardSlvOut16{
|
||||
val out = IO(Output(UInt(16.W)))
|
||||
val outReg = RegInit(0.U(16.W))
|
||||
|
||||
when( isCrcPass & downRegTemp(0)(3,0) === 0.U ){
|
||||
outReg := Cat(downRegTemp(13), downRegTemp(12))
|
||||
}
|
||||
when( isCrcPass & downRegTemp(0)(3,0) === 0.U ){
|
||||
mthodReg := Cat(downRegTemp(9), downRegTemp(8))
|
||||
valueReg := Cat(downRegTemp(11), downRegTemp(10))
|
||||
}
|
||||
|
||||
outRegSync := RegEnable( outReg, 0.U, isUpdate )
|
||||
|
||||
when( statusPage === 0.U ){
|
||||
upReg(8) := mthodReg(7,0)
|
||||
upReg(9) := mthodReg(15,8)
|
||||
|
||||
upReg(10) := valueReg(7,0)
|
||||
upReg(11) := valueReg(15,8)
|
||||
|
||||
upReg(12) := outReg(7,0)
|
||||
upReg(13) := outReg(15,8)
|
||||
}
|
||||
|
||||
out := ~outPin
|
||||
|
||||
}
|
||||
|
||||
|
||||
class DOut16c extends DOut16 with DoutInspect
|
||||
class DOut16p extends DOut16 with DoutInspect_Plus
|
||||
@@ -1,137 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
class ManualParamBundle extends Bundle{
|
||||
val data2 = UInt(8.W)
|
||||
val data3 = UInt(8.W)
|
||||
val data4 = UInt(8.W)
|
||||
val data5 = UInt(8.W)
|
||||
val data6 = UInt(8.W)
|
||||
val data7 = UInt(8.W)
|
||||
val data8 = UInt(8.W)
|
||||
val data9 = UInt(8.W)
|
||||
|
||||
val vendorID = UInt( 16.W )
|
||||
val moduleID = UInt( 16.W )
|
||||
val hwVersion = UInt( 16.W )
|
||||
val swVersion = UInt( 16.W )
|
||||
val serial = UInt( 48.W )
|
||||
}
|
||||
|
||||
|
||||
abstract class BackBoardSlvLocal extends BackBoardSlvBase with BackBoardSlvDown with BackBoardSlvUp{
|
||||
|
||||
val param = IO(Input( new ManualParamBundle ))
|
||||
|
||||
val statusPage = RegEnable( downRegTemp(0)(3,0), 15.U, isCrcPass )
|
||||
val statusP = RegInit(false.B)
|
||||
val statusRF = RegInit(false.B)
|
||||
val statusPR = RegInit(0.U(2.W))
|
||||
val statusER = RegInit(false.B)
|
||||
val statusLE = RegInit(false.B)
|
||||
val statusSync = RegEnable( downRegTemp(1).extract(3).asBool, false.B, isCrcPass )
|
||||
val statusNone = ~ShiftRegister(io.isLast, 2)
|
||||
val customData = for( i <- 0 until 3 ) yield {
|
||||
RegEnable( downRegTemp(1).extract(5+i), false.B, isCrcPass )
|
||||
}
|
||||
|
||||
upReg(0) := Cat( statusPR.extract(0), statusRF, statusP, 0.U(1.W), statusPage )
|
||||
upReg(1) := Cat( customData(2), customData(1), customData(0), statusNone, statusSync, statusLE, statusER, statusPR.extract(1) )
|
||||
|
||||
when( statusPage === 15.U ){
|
||||
upReg(2) := param.data2
|
||||
upReg(3) := param.data3
|
||||
upReg(4) := param.data4
|
||||
upReg(5) := param.data5
|
||||
upReg(6) := param.data6
|
||||
upReg(7) := param.data7
|
||||
upReg(8) := param.data8
|
||||
upReg(9) := param.data9
|
||||
|
||||
|
||||
upReg(10) := param.vendorID(7,0)
|
||||
upReg(11) := param.vendorID(15,8)
|
||||
|
||||
upReg(12) := param.moduleID(7,0)
|
||||
upReg(13) := param.moduleID(15,8)
|
||||
|
||||
upReg(14) := param.hwVersion(7,0)
|
||||
upReg(15) := param.hwVersion(15,8)
|
||||
|
||||
upReg(16) := param.swVersion(7,0)
|
||||
upReg(17) := param.swVersion(15,8)
|
||||
|
||||
upReg(18) := param.serial(7,0)
|
||||
upReg(19) := param.serial(15,8)
|
||||
upReg(20) := param.serial(23,16)
|
||||
upReg(21) := param.serial(31,24)
|
||||
upReg(22) := param.serial(39,32)
|
||||
upReg(23) := param.serial(47,40)
|
||||
}
|
||||
|
||||
|
||||
|
||||
val (usCounter, usTrigger) = Counter(Range(0, 10))
|
||||
|
||||
io.isOnline := false.B
|
||||
|
||||
val isUpdate = (statusSync & ShiftRegister(io.DCIn, 3)) | (~statusSync)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
trait BackBoardSlvStatusPR { this: BackBoardSlvLocal =>
|
||||
val flashCounter = RegInit( 0.U( 19.W ) )
|
||||
val flash2HZ = Reg(Bool())
|
||||
val flash1HZ = Reg(Bool())
|
||||
|
||||
|
||||
when( usTrigger ){
|
||||
when( flashCounter >= 500000.U ){
|
||||
flashCounter := 0.U
|
||||
flash2HZ := ~flash2HZ
|
||||
when( flash2HZ ){
|
||||
flash1HZ := ~flash1HZ
|
||||
}
|
||||
} .otherwise{
|
||||
flashCounter := flashCounter + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
val LED_PR = IO(Output( Bool() ))
|
||||
|
||||
LED_PR := ~Mux( statusPR === "b00".U, flash2HZ,
|
||||
Mux( statusPR === "b01".U, flash1HZ,
|
||||
Mux( statusPR === "b10".U, false.B, true.B
|
||||
)))
|
||||
|
||||
|
||||
val watchDogTarget = RegInit( 0.U( 19.W ) )
|
||||
|
||||
when( isCrcPass ){
|
||||
watchDogTarget := flashCounter
|
||||
}
|
||||
|
||||
when( isCrcPass ){
|
||||
statusPR := Cat( downRegTemp(1).extract(0), downRegTemp(0).extract(7) )
|
||||
} .elsewhen( ((watchDogTarget === (flashCounter + 1.U)) | (watchDogTarget === 0.U & (flashCounter >= 500000.U))) & usTrigger ){
|
||||
statusPR := 0.U
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,335 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
|
||||
class MirrorSRAMDown() extends BlackBox with HasBlackBoxInline {
|
||||
class MirrorSRAMDownIO extends Bundle{
|
||||
val addrr = Input(UInt(11.W))
|
||||
val addrw = Input(UInt(10.W))
|
||||
|
||||
val dataw = Input( UInt(16.W) )
|
||||
val datar = Output( UInt(8.W) )
|
||||
val enw = Input(Bool())
|
||||
val enr = Input(Bool())
|
||||
|
||||
val clockr = Input(Bool())
|
||||
val clockw = Input(Bool())
|
||||
|
||||
}
|
||||
val io: MirrorSRAMDownIO = IO(new MirrorSRAMDownIO)
|
||||
|
||||
setInline("MirrorSRAMDown.v",
|
||||
"""
|
||||
| module MirrorSRAMDown(
|
||||
| input [15:0] dataw,
|
||||
| input [9:0] addrw,
|
||||
| input enw,
|
||||
|
|
||||
| output [7:0] datar,
|
||||
| input [10:0] addrr,
|
||||
| input enr,
|
||||
|
|
||||
| input clockr,
|
||||
| input clockw
|
||||
| );
|
||||
|
|
||||
| reg [15:0] ram[0:1023];
|
||||
| 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 addrr[0] ? ram[addrr[10:1]][15:8] : ram[addrr[10:1]][7:0];
|
||||
| end
|
||||
| end
|
||||
|
|
||||
| assign datar = data_r_reg;
|
||||
|
|
||||
| initial begin
|
||||
| for ( integer i = 0; i < 1024; i = i + 1 ) begin
|
||||
| ram[i] = $random;
|
||||
| end
|
||||
|
|
||||
| data_r_reg = $random;
|
||||
| end
|
||||
|
|
||||
|endmodule
|
||||
""".stripMargin)
|
||||
}
|
||||
|
||||
|
||||
class MirrorSRAMUp extends BlackBox with HasBlackBoxInline {
|
||||
|
||||
class MirrorSRAMUpIO extends Bundle{
|
||||
val addrr = Input(UInt(10.W))
|
||||
val addrw = Input(UInt(11.W))
|
||||
|
||||
val dataw = Input( UInt(8.W) )
|
||||
val datar = Output( UInt(16.W) )
|
||||
val enw = Input(Bool())
|
||||
val enr = Input(Bool())
|
||||
|
||||
val clockr = Input(Bool())
|
||||
val clockw = Input(Bool())
|
||||
|
||||
}
|
||||
val io: MirrorSRAMUpIO = IO(new MirrorSRAMUpIO)
|
||||
|
||||
setInline("MirrorSRAMUp.v",
|
||||
"""
|
||||
| module MirrorSRAMUp(
|
||||
| input [7:0] dataw,
|
||||
| input [10:0] addrw,
|
||||
| input enw,
|
||||
|
|
||||
| output [15:0] datar,
|
||||
| input [9:0] addrr,
|
||||
| input enr,
|
||||
|
|
||||
| input clockr,
|
||||
| input clockw
|
||||
| );
|
||||
|
|
||||
| reg [7:0] ram[0:2047] /* synthesis syn_ramstyle="block_ram" */;
|
||||
| reg [15: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[2*addrr+1], ram[2*addrr] };
|
||||
| end
|
||||
| end
|
||||
|
|
||||
| assign datar = data_r_reg;
|
||||
|
|
||||
|
|
||||
|endmodule
|
||||
""".stripMargin)
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MirrorSRAMDP extends BlackBox with HasBlackBoxInline {
|
||||
|
||||
class MirrorSRAMDPIO extends Bundle{
|
||||
|
||||
val addrA = Input(UInt(10.W))
|
||||
val datawA = Input( UInt(16.W) )
|
||||
val datarA = Output( UInt(16.W) )
|
||||
val enwA = Input(Bool())
|
||||
val enrA = Input(Bool())
|
||||
val clockA = Input(Bool())
|
||||
|
||||
|
||||
val addrB = Input(UInt(10.W))
|
||||
val datawB = Input( UInt(16.W) )
|
||||
val datarB = Output( UInt(16.W) )
|
||||
val enwB = Input(Bool())
|
||||
val enrB = Input(Bool())
|
||||
val clockB = Input(Bool())
|
||||
|
||||
}
|
||||
val io: MirrorSRAMDPIO = IO(new MirrorSRAMDPIO)
|
||||
|
||||
setInline("MirrorSRAMDP.v",
|
||||
"""
|
||||
| module MirrorSRAMDP(
|
||||
| input [15:0] datawA,
|
||||
| input [9:0] addrA,
|
||||
| input enwA,
|
||||
| input enrA,
|
||||
| output [15:0] datarA,
|
||||
| input clockA,
|
||||
|
|
||||
| input [15:0] datawB,
|
||||
| input [9:0] addrB,
|
||||
| input enwB,
|
||||
| input enrB,
|
||||
| output [15:0] datarB,
|
||||
| input clockB
|
||||
| );
|
||||
|
|
||||
| reg [15:0] mem[0:1023];
|
||||
| reg [15:0] data_outa_reg = 16'b0;
|
||||
| reg [15:0] data_outb_reg = 16'b0;
|
||||
|
|
||||
| assign datarA = data_outa_reg;
|
||||
| assign datarB = data_outb_reg;
|
||||
|
|
||||
| always@( posedge clockA ) begin
|
||||
| if( enrA ) begin
|
||||
| end
|
||||
|
|
||||
| if( enwA ) begin
|
||||
| mem[addrA] <= datawA;
|
||||
| end else begin
|
||||
| data_outa_reg <= mem[addrA];
|
||||
| end
|
||||
| end
|
||||
|
|
||||
|
|
||||
| always@( posedge clockB ) begin
|
||||
| if(enrB) begin
|
||||
| end
|
||||
|
|
||||
| if( enwB ) begin
|
||||
| mem[addrB] <= datawB;
|
||||
| end else begin
|
||||
| data_outb_reg <= mem[addrB];
|
||||
| end
|
||||
| end
|
||||
|
|
||||
| initial begin
|
||||
| for( integer i = 0; i < 1024; i = i + 1 ) begin
|
||||
| mem[i] = $random;
|
||||
| end
|
||||
| end
|
||||
|
|
||||
| //Gowin_DPB your_instance_name(
|
||||
| // .douta(datarA), //output [15:0] douta
|
||||
| // .doutb(datarB), //output [15:0] doutb
|
||||
| // .clka(clockA), //input clka
|
||||
| // .ocea(1'b1), //input ocea
|
||||
| // .cea(1'b1), //input cea
|
||||
| // .reseta(1'b0), //input reseta
|
||||
| // .wrea(enwA), //input wrea
|
||||
| // .clkb(clockB), //input clkb
|
||||
| // .oceb(1'b1), //input oceb
|
||||
| // .ceb(1'b1), //input ceb
|
||||
| // .resetb(1'b0), //input resetb
|
||||
| // .wreb(enwB), //input wreb
|
||||
| // .ada(addrA), //input [3:0] ada
|
||||
| // .dina(datawA), //input [15:0] dina
|
||||
| // .adb(addrB), //input [3:0] adb
|
||||
| // .dinb(datawB) //input [15:0] dinb
|
||||
| //);
|
||||
|
|
||||
|endmodule
|
||||
""".stripMargin)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class SpiSRAMDown() extends BlackBox with HasBlackBoxInline {
|
||||
class SpiSRAMDownIO extends Bundle{
|
||||
val addrr = Input(UInt(9.W))
|
||||
val addrw = Input(UInt(9.W))
|
||||
|
||||
val dataw = Input( UInt(8.W) )
|
||||
val datar = Output( UInt(8.W) )
|
||||
val enw = Input(Bool())
|
||||
val enr = Input(Bool())
|
||||
|
||||
val clockr = Input(Bool())
|
||||
val clockw = Input(Bool())
|
||||
|
||||
}
|
||||
val io: SpiSRAMDownIO = IO(new SpiSRAMDownIO)
|
||||
|
||||
setInline("SpiSRAMDown.v",
|
||||
"""
|
||||
| module SpiSRAMDown(
|
||||
| input [7:0] dataw,
|
||||
| input [8:0] addrw,
|
||||
| input enw,
|
||||
|
|
||||
| output [7:0] datar,
|
||||
| input [8:0] addrr,
|
||||
| input enr,
|
||||
|
|
||||
| input clockr,
|
||||
| input clockw
|
||||
| );
|
||||
|
|
||||
| reg [7:0] ram[0:511];
|
||||
| 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;
|
||||
|
|
||||
|
|
||||
|endmodule
|
||||
""".stripMargin)
|
||||
}
|
||||
|
||||
|
||||
class SpiSRAMUp extends BlackBox with HasBlackBoxInline {
|
||||
|
||||
class SpiSRAMUpIO extends Bundle{
|
||||
val addrr = Input(UInt(9.W))
|
||||
val addrw = Input(UInt(9.W))
|
||||
|
||||
val dataw = Input( UInt(8.W) )
|
||||
val datar = Output( UInt(8.W) )
|
||||
val enw = Input(Bool())
|
||||
val enr = Input(Bool())
|
||||
|
||||
val clockr = Input(Bool())
|
||||
val clockw = Input(Bool())
|
||||
|
||||
}
|
||||
val io: SpiSRAMUpIO = IO(new SpiSRAMUpIO)
|
||||
|
||||
setInline("SpiSRAMUp.v",
|
||||
"""
|
||||
| module SpiSRAMUp(
|
||||
| input [7:0] dataw,
|
||||
| input [8:0] addrw,
|
||||
| input enw,
|
||||
|
|
||||
| output [7:0] datar,
|
||||
| input [8:0] addrr,
|
||||
| input enr,
|
||||
|
|
||||
| input clockr,
|
||||
| input clockw
|
||||
| );
|
||||
|
|
||||
| reg [7:0] ram[0:511];
|
||||
| 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;
|
||||
|
|
||||
|
|
||||
|endmodule
|
||||
""".stripMargin)
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
trait BackBoardSlvQei{ this: BackBoardSlvLocal =>
|
||||
val phaseA = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val phaseB = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val phaseZ = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val counter = for( i <- 0 until 2 ) yield { Reg(UInt(33.W)) }
|
||||
val encordNxt = for( i <- 0 until 2 ) yield { Cat( phaseB(i), phaseA(i) ) }
|
||||
val encordCur = for( i <- 0 until 2 ) yield { RegNext(encordNxt(i)) }
|
||||
|
||||
val isEnable = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isSign = for( i <- 0 until 2 ) yield { Reg(Bool()) }
|
||||
val isSetVal = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val initVal = for( i <- 0 until 2 ) yield { Reg(UInt(32.W)) }
|
||||
val mode = for( i <- 0 until 2 ) yield { Reg(UInt(2.W)) }
|
||||
val invDirect = for( i <- 0 until 2 ) yield { Reg(Bool()) }
|
||||
val is2Phase = for( i <- 0 until 2 ) yield { Reg(Bool()) }
|
||||
val isZPhaseEnable = for( i <- 0 until 2 ) yield { Reg(Bool()) }
|
||||
val isSetValPos = for( i <- 0 until 2 ) yield { ~RegNext( isSetVal(i), false.B ) & isSetVal(i) }
|
||||
val isSetValNeg = for( i <- 0 until 2 ) yield { RegNext( isSetVal(i), false.B ) & ~isSetVal(i) }
|
||||
|
||||
val isAdvA = for( i <- 0 until 2 ) yield {
|
||||
( encordCur(i) === "b00".U & encordNxt(i) === "b01".U & mode(i).extract(1)) |
|
||||
( encordCur(i) === "b01".U & encordNxt(i) === "b11".U & mode(i) =/= "b00".U ) |
|
||||
( encordCur(i) === "b11".U & encordNxt(i) === "b10".U & mode(i).extract(1)) |
|
||||
( encordCur(i) === "b10".U & encordNxt(i) === "b00".U )
|
||||
}
|
||||
|
||||
|
||||
val isAdvB = for( i <- 0 until 2 ) yield {
|
||||
( encordNxt(i) === "b00".U & encordCur(i) === "b01".U ) |
|
||||
( encordNxt(i) === "b01".U & encordCur(i) === "b11".U & mode(i).extract(1)) |
|
||||
( encordNxt(i) === "b11".U & encordCur(i) === "b10".U & mode(i) =/= "b00".U ) |
|
||||
( encordNxt(i) === "b10".U & encordCur(i) === "b00".U & mode(i).extract(1))
|
||||
}
|
||||
|
||||
val isMiss = for( i <- 0 until 2 ) yield { encordCur(i) === ~encordNxt(i) }
|
||||
// val isKeep = for( i <- 0 until 2 ) yield { encordCur(i) === encordNxt(i) }
|
||||
val isOverflow = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val isCounter32Flip = for( i <- 0 until 2 ) yield { RegNext( counter(i).extract(32)) =/= counter(i).extract(32) }
|
||||
val isCounter31Flip = for( i <- 0 until 2 ) yield { (RegNext( counter(i).extract(31)) =/= counter(i).extract(31)) & (RegNext( counter(i).extract(32)) === counter(i).extract(32)) }
|
||||
|
||||
|
||||
for( i <- 0 until 2 ){
|
||||
|
||||
|
||||
isOverflow(i) := false.B
|
||||
|
||||
when( isZPhaseEnable(i) & phaseZ(i) ){ //Z Phase reset
|
||||
counter(i) := initVal(i)
|
||||
} .elsewhen( isSetValPos(i) ){
|
||||
counter(i) := initVal(i)
|
||||
} .elsewhen( isSetValNeg(i) ){
|
||||
counter(i) := 0.U
|
||||
} .otherwise{
|
||||
when(isEnable(i)){
|
||||
when(~is2Phase(i)){ //A Phase only
|
||||
when( RegNext( phaseA(i) ) & ~phaseA(i) ){
|
||||
counter(i) := counter(i) + 1.U
|
||||
}
|
||||
|
||||
isOverflow(i) := isSetVal(i) & isCounter32Flip(i)
|
||||
|
||||
} .otherwise{ //AB Phase
|
||||
|
||||
when( invDirect(i) ) {
|
||||
when(isAdvA(i)){
|
||||
counter(i) := counter(i) - 1.U
|
||||
} .elsewhen(isAdvB(i)){
|
||||
counter(i) := counter(i) + 1.U
|
||||
}
|
||||
} .otherwise{ //~invDirect(i)
|
||||
when(isAdvA(i)){
|
||||
counter(i) := counter(i) + 1.U
|
||||
} .elsewhen(isAdvB(i)){
|
||||
counter(i) := counter(i) - 1.U
|
||||
}
|
||||
}
|
||||
|
||||
isOverflow(i) :=
|
||||
Mux( isSign(i), isSetVal(i) & isCounter31Flip(i), isSetVal(i) & isCounter32Flip(i) )
|
||||
}
|
||||
|
||||
} .otherwise{ //~isEnable
|
||||
counter(i) := initVal(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class Qei extends BackBoardSlvLocal with BackBoardSlvStatusPR with BackBoardSlvQei{
|
||||
val phaseAIO = for( i <- 0 until 2 ) yield { IO(Input(Bool())) }
|
||||
val phaseBIO = for( i <- 0 until 2 ) yield { IO(Input(Bool())) }
|
||||
val phaseZIO = for( i <- 0 until 2 ) yield { IO(Input(Bool())) }
|
||||
|
||||
|
||||
for( i <- 0 until 2 ){
|
||||
phaseA(i) := RegNext(phaseAIO(i))
|
||||
phaseB(i) := RegNext(phaseBIO(i))
|
||||
phaseZ(i) := RegNext(phaseZIO(i))
|
||||
}
|
||||
|
||||
for( i <- 0 until 2 ){
|
||||
|
||||
when(isOverflow(i)){
|
||||
isEnable(i) := false.B
|
||||
} .elsewhen( (isCrcPass & downRegTemp(0)(3,0) === 0.U) & ~downRegTemp(2+i).extract(0) ){
|
||||
isEnable(i) := false.B
|
||||
} .elsewhen( (isCrcPass & downRegTemp(0)(3,0) === 0.U) & downRegTemp(2+i).extract(0) ){
|
||||
isEnable(i) := true.B
|
||||
}
|
||||
|
||||
when( isCrcPass & downRegTemp(0)(3,0) === 0.U ){
|
||||
isZPhaseEnable(i) := downRegTemp(2+(2*i)).extract(1)
|
||||
is2Phase(i) := downRegTemp(2+(2*i)).extract(2)
|
||||
isSetVal(i) := downRegTemp(2+(2*i)).extract(3)
|
||||
mode(i) := downRegTemp(2+(2*i))(5,4)
|
||||
invDirect(i) := downRegTemp(2+(2*i)).extract(6)
|
||||
isSign(i) := downRegTemp(2+(2*i)).extract(7)
|
||||
|
||||
}
|
||||
|
||||
when( (isCrcPass & downRegTemp(0)(3,0) === 0.U) & ~downRegTemp(2+i).extract(3) ){
|
||||
initVal(i) := 0.U
|
||||
} .elsewhen( (isCrcPass & downRegTemp(0)(3,0) === 0.U) & downRegTemp(2+i).extract(3) ){
|
||||
initVal(i) := Cat( downRegTemp(9+(4*i)), downRegTemp(8+(4*i)), downRegTemp(7+(4*i)), downRegTemp(6+(4*i)) )
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val cntLatch = for( i <- 0 until 2 ) yield { RegEnable(counter(i), ~RegNext(io.lvdsSlv.upstream_tx_data_ready, false.B) & io.lvdsSlv.upstream_tx_data_ready ) }
|
||||
|
||||
|
||||
when( statusPage === 0.U ){
|
||||
upReg(2) := Cat( isSign(0), invDirect(0), mode(0), isSetVal(0), is2Phase(0), isZPhaseEnable(0), isEnable(0) )
|
||||
upReg(3) := 0.U
|
||||
upReg(4) := Cat( isSign(1), invDirect(1), mode(1), isSetVal(1), is2Phase(1), isZPhaseEnable(1), isEnable(1) )
|
||||
upReg(5) := 0.U
|
||||
|
||||
upReg(6) := cntLatch(0)(7,0)
|
||||
upReg(7) := cntLatch(0)(15,8)
|
||||
upReg(8) := cntLatch(0)(23,16)
|
||||
upReg(9) := cntLatch(0)(31,24)
|
||||
|
||||
upReg(10) := cntLatch(1)(7,0)
|
||||
upReg(11) := cntLatch(1)(15,8)
|
||||
upReg(12) := cntLatch(1)(23,16)
|
||||
upReg(13) := cntLatch(1)(31,24)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# 背板总线
|
||||
|
||||
## 用户接口
|
||||
|
||||
|
||||
* 数据地址线 AD 16比特位宽
|
||||
|
||||
* 地址锁存 ADVn 负逻辑
|
||||
* 读使能 RDn 负逻辑
|
||||
* 写使能 WRn 负逻辑
|
||||
* 片选 CSn 负逻辑
|
||||
|
||||
|
||||
使用要求:地址锁存时ADV保持高至少30ns, 写入时CS,WR保持高至少30ns,读出时CS,RD保持高至少30ns方可读取数据线上数据
|
||||
--------------------------------------
|
||||
|
||||
### 内存空间映射
|
||||
|
||||
* 总线上最多允许挂载64个从站,每个从站有8bits*32个下行寄存器(只写),8bits*32个上行寄存器(只读)
|
||||
* 当地址线第11比特(AD[10])为低时,FSMC访问(只读或者只写)从站镜像寄存器(以8比特形式组织),
|
||||
- 通过16比特写用户接口 0x00 ~ 0x1F, 可以将数据同步写入到从站0的16个下行寄存器(只写)中,后续从站地址按序分配
|
||||
- 通过16比特读用户接口 0x00 ~ 0x1F, 可以将数据同步写入到从站0的16个上行寄存器(只读)中,后续从站地址按序分配
|
||||
* 当地址线第11比特(AD[10])为高时,FSMC通过地址9到0比特访问(可读可写)主站寄存器全部定义为16比特
|
||||
- 0x00 控制状态,
|
||||
+ statusCDRErr: 第4比特,表示LVDS总线发生CDR解析错误,写1清零
|
||||
+ statusCRCErr: 第3比特,表示LVDS总线发生传输CRC错误,写1清零
|
||||
+ statusLinkErr: 第2比特,表示LVDS总线发生从站掉线,写1清零
|
||||
+ statusSynch: 第1比特,表示LVDS总线各个从站已经同步,初始化完成时且ctrlSynch为高自动置高,手动将ctrlInit置高时自动置低
|
||||
+ statusInit: 第0比特,表示LVDS总线已经初始化,初始化完成时自动置高,手动将ctrlInit置高时自动置低
|
||||
- 0x01 操作寄存器
|
||||
+ ctrlTransmit: 第5比特,手动写入1将触发LVDS总线传输,传输完成将自动清零
|
||||
+ ctrlSynch: 第1比特,手动写入1表示初始化的同时同步所有从站
|
||||
+ ctrlInit: 第0比特,手动写入1将触发LVDS总线初始化,初始化完成将自动清零
|
||||
|
||||
- 0x02 配置从栈数量(减一): 从站数量当前无法手动配置,初始化过程中将自动检测在线从站数量,并以该数量进行初始化,从站数量将自动写入该寄存器
|
||||
- 0x03 离线位置: 当发生从站掉线,该寄存器可读出掉线从站编号
|
||||
@@ -1,153 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
trait BackBoardSpiSlv{ this: BackBoardSlvLocal =>
|
||||
|
||||
val sck = Wire(Bool())
|
||||
val mosi = Wire(Bool())
|
||||
val csn = Wire(Bool())
|
||||
val clk100M = Wire(Bool())
|
||||
|
||||
val spiRegDown = Module(new SpiSRAMDown)
|
||||
val spiRegUp = Module(new SpiSRAMUp)
|
||||
|
||||
|
||||
spiRegDown.io.clockr := clk100M
|
||||
spiRegDown.io.clockw := clock.asBool
|
||||
|
||||
spiRegUp.io.clockr := clock.asBool
|
||||
spiRegUp.io.clockw := clk100M
|
||||
|
||||
|
||||
val localUpdate = RegInit(0.U(16.W))
|
||||
|
||||
val shiftSCK = withClockAndReset( clk100M.asClock, reset ){ ShiftRegisters(sck, 3, false.B, true.B) }
|
||||
val shiftCSn = withClockAndReset( clk100M.asClock, reset ){ ShiftRegisters(csn, 3, true.B, true.B) }
|
||||
val shiftMOSI = withClockAndReset( clk100M.asClock, reset ){ ShiftRegisters(mosi, 3) }
|
||||
|
||||
|
||||
val isSckPosedge = ~shiftSCK(2) & shiftSCK(1)
|
||||
val isSckPosedgeNext = withClockAndReset( clk100M.asClock, reset ){ ShiftRegisters(isSckPosedge, 2, false.B, true.B) }
|
||||
|
||||
|
||||
val exReg_100M = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(8.W)) }
|
||||
val exMask_100M = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(16.W)) }
|
||||
val cmd_100M = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(8.W)) }
|
||||
val pageSel = cmd_100M(5,4)
|
||||
val spiCmd = cmd_100M(3,0)
|
||||
|
||||
val bitSel = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(3.W)) }
|
||||
val byteSel = withClockAndReset( clk100M.asClock, reset ){ Reg(UInt(5.W)) }
|
||||
|
||||
|
||||
spiRegDown.io.addrr := Cat(pageSel, byteSel)
|
||||
spiRegDown.io.enr := spiCmd === 0.U & isSckPosedgeNext(0)
|
||||
|
||||
spiRegUp.io.addrw := Cat(pageSel, byteSel - 1.U)
|
||||
spiRegUp.io.dataw := withClockAndReset( clk100M.asClock, reset ){ RegEnable(exReg_100M, bitSel === 0.U) }
|
||||
spiRegUp.io.enw := isSckPosedgeNext(1) & ~shiftCSn(1+1) & bitSel === 0.U & spiCmd === 1.U
|
||||
|
||||
withClockAndReset( clk100M.asClock, reset ){//100M
|
||||
|
||||
when( shiftCSn(2) & ~shiftCSn(1) ){
|
||||
bitSel := 0.U
|
||||
byteSel := 0.U
|
||||
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
|
||||
bitSel := bitSel + 1.U
|
||||
when( bitSel === 7.U ){
|
||||
byteSel := byteSel + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
|
||||
bitSel := 0.U
|
||||
byteSel := 0.U
|
||||
cmd_100M := 0.U
|
||||
} .elsewhen( isSckPosedge & ~shiftCSn(1) & byteSel === 0.U ){ //CS为低,且SCK上跳的第0byte
|
||||
cmd_100M := Cat( cmd_100M(6,0), shiftMOSI(1) )
|
||||
}
|
||||
|
||||
when( shiftCSn(2) & ~shiftCSn(1) ){ //CS下跳
|
||||
exReg_100M := upReg(0)
|
||||
} .elsewhen( isSckPosedgeNext(1) & ~shiftCSn(1) & bitSel === 0.U ){ //CS为低,且SCK上跳补一拍 的第0bit
|
||||
when( byteSel === 1.U ){
|
||||
exReg_100M := upReg(1)
|
||||
} .elsewhen( spiCmd === 2.U & byteSel === 2.U ){
|
||||
exReg_100M := localUpdate(7,0)
|
||||
} .elsewhen( spiCmd === 2.U & byteSel === 3.U ){
|
||||
exReg_100M := localUpdate(15,8)
|
||||
} .elsewhen( spiCmd === 0.U & (byteSel =/= 0.U | byteSel =/= 1.U) ){
|
||||
exReg_100M := spiRegDown.io.datar
|
||||
}
|
||||
} .elsewhen( isSckPosedge & ~shiftCSn(1) ){
|
||||
exReg_100M := Cat( exReg_100M(6 ,0), shiftMOSI(1) )
|
||||
}
|
||||
|
||||
|
||||
when( isSckPosedgeNext(1) & ~shiftCSn(1) & byteSel === 3.U & bitSel === 0.U & spiCmd === 3.U ){
|
||||
exMask_100M := Cat( exReg_100M, exMask_100M(7,0) )
|
||||
} .elsewhen( isSckPosedgeNext(1) & ~shiftCSn(1) & byteSel === 4.U & bitSel === 0.U & spiCmd === 3.U ){
|
||||
exMask_100M := Cat( exMask_100M(15,8), exReg_100M )
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SpiSlv extends BackBoardSlvLocal
|
||||
with BackBoardSlvStatusPR
|
||||
with BackBoardSpiSlv{
|
||||
|
||||
val spi = IO(new Bundle{
|
||||
val sck = Input(Bool())
|
||||
val mosi = Input(Bool())
|
||||
val miso = Output(Bool())
|
||||
val csn = Input(Bool())
|
||||
})
|
||||
val clk100MIO = IO(Input(Bool()))
|
||||
val interrupt = IO(Output(Bool()))
|
||||
|
||||
sck := spi.sck
|
||||
mosi := spi.mosi
|
||||
csn := spi.csn
|
||||
spi.miso := exReg_100M.extract(exReg_100M.getWidth-1)
|
||||
clk100M := clk100MIO
|
||||
|
||||
val shiftCSn_10M = ShiftRegisters(csn, 3, true.B, true.B)
|
||||
|
||||
|
||||
when( isCrcPass ){
|
||||
localUpdate := localUpdate & ~( 1.U << downRegTemp(0)(3,0) )
|
||||
} .elsewhen( ~shiftCSn_10M(2) & shiftCSn_10M(1) ){
|
||||
localUpdate := localUpdate & ~exMask_100M
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
spiRegDown.io.enw := io.lvdsSlv.downstream_rx_data_valid & (downCnt =/= 0.U | downCnt =/= 1.U)
|
||||
spiRegDown.io.dataw := io.lvdsSlv.downstream_rx_data_out
|
||||
spiRegDown.io.addrw := Cat( downRegTemp(0)(3,0), downCnt(4,0))
|
||||
|
||||
spiRegUp.io.enr := io.lvdsSlv.upstream_tx_data_ready
|
||||
spiRegUp.io.addrr := Cat( statusPage, upCnt(4,0)+1.U )
|
||||
|
||||
|
||||
io.lvdsSlv.upstream_tx_data_in :=
|
||||
Mux(upCnt === 0.U | upCnt === 1.U | statusPage === 15.U, upReg(upCnt), spiRegUp.io.datar)
|
||||
|
||||
val int = RegInit(false.B); interrupt := int
|
||||
when( int ){
|
||||
int := false.B
|
||||
} .elsewhen( RegNext(io.lvdsSlv.upstream_tx_data_ready, false.B) & ~io.lvdsSlv.upstream_tx_data_ready ){
|
||||
int := true.B
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
class Axis8toNIO_Bundle(dw: Int) extends Bundle{
|
||||
val enq = Flipped(Decoupled(new AxisNto8IO_Bundle(8)))
|
||||
val deq = Decoupled(new AxisNto8IO_Bundle(dw))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class Axis8toN(dw: Int) extends Module{
|
||||
|
||||
require( dw == 16 | dw == 32 | dw == 64 )
|
||||
assert( io.deq.ready === true.B )
|
||||
|
||||
val io: Axis8toNIO_Bundle = IO(new Axis8toNIO_Bundle(dw))
|
||||
|
||||
val cnt = RegInit( 0.U( log2Ceil(dw/8).W ) )
|
||||
|
||||
val fifo = Reg( new AxisNto8IO_Bundle(dw) )
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
class AxisNto8IO_Bundle(dw: Int) extends Bundle{
|
||||
val enq = Flipped(Decoupled(new AxisNto8IO_Bundle(dw)))
|
||||
val deq = Decoupled(new AxisNto8IO_Bundle(8))
|
||||
}
|
||||
|
||||
|
||||
class AxisNto8(dw: Int) extends Module{
|
||||
|
||||
require( dw == 16 | dw == 32 | dw == 64 )
|
||||
|
||||
val io: AxisNto8IO_Bundle = IO(new AxisNto8IO_Bundle(dw))
|
||||
|
||||
val cnt = RegInit( 0.U( log2Ceil(dw/8).W ) )
|
||||
val isBusy = RegInit(false.B)
|
||||
|
||||
val fifo = RegEnable( io.enq.bits, io.enq.fire )
|
||||
io.enq.ready := ~isBusy | (io.deq.fire & cnt.andR)
|
||||
|
||||
|
||||
|
||||
|
||||
when( io.deq.fire ){
|
||||
cnt := cnt + 1.U
|
||||
}
|
||||
|
||||
when( io.enq.fire ){
|
||||
isBusy := true.B
|
||||
} .elsewhen( io.deq.fire & cnt.andR ){
|
||||
isBusy := false.B
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
io.deq.valid := isBusy
|
||||
io.deq.bits.tdata := fifo.tdata >> (cnt << 3)
|
||||
io.deq.bits.tlast := fifo.tlast & cnt.andR
|
||||
io.deq.bits.tuser := fifo.tuser & cnt.andR
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
class BackBoardMstIO extends Bundle{
|
||||
val downStreamReqDat = Input( Bool() )
|
||||
val downStreamRespdat = Output(Bool())
|
||||
|
||||
val CS = Input(Bool())
|
||||
val MISO = Output(Bool())
|
||||
val MOSI = Input(Bool())
|
||||
val SCK = Input(Bool())
|
||||
|
||||
val interrupt = Output(Bool())
|
||||
|
||||
val clk4 = Input( Bool() )
|
||||
|
||||
}
|
||||
|
||||
|
||||
class BackBoardMst extends Module{
|
||||
val io: BackBoardMstIO = IO(new BackBoardMstIO)
|
||||
|
||||
|
||||
val spi = Module( new SpiSlv )
|
||||
val in = Module( new CDR4MultiIn )
|
||||
val out = Module( new CDROutBus )
|
||||
|
||||
spi.io.CS := io.CS
|
||||
io.MISO := spi.io.MISO
|
||||
spi.io.MOSI := io.MOSI
|
||||
spi.io.SCK := io.SCK
|
||||
|
||||
// io.interrupt := spi.io.interrupt
|
||||
io.interrupt := false.B
|
||||
|
||||
spi.io.CDRIn <> in.io.latDat
|
||||
spi.io.CDROut <> out.io.pkgDat
|
||||
|
||||
in.io.clk4 := io.clk4
|
||||
spi.io.clk4 := io.clk4
|
||||
|
||||
in.io.dat := io.downStreamReqDat
|
||||
io.downStreamRespdat := out.io.dat
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
class BackBoardSlvIO extends Bundle{
|
||||
val localHost = Input(UInt(5.W))
|
||||
|
||||
val upStreamReqDat = Input( Bool() )
|
||||
val downStreamReqDat = Input( Bool() )
|
||||
|
||||
val upStreamRespdat = Output(Bool())
|
||||
val downStreamRespdat = Output(Bool())
|
||||
|
||||
val clk4 = Input( Bool() )
|
||||
}
|
||||
|
||||
|
||||
abstract class BackBoardSlvBase extends Module{
|
||||
val io: BackBoardSlvIO = IO(new BackBoardSlvIO)
|
||||
|
||||
|
||||
val upStreamReq = Module(new CDR4MultiIn)
|
||||
val downStreamReq = Module(new CDR4MultiIn)
|
||||
|
||||
val upStreamResp = Module(new CDROutBus)
|
||||
val downStreamResp = Module(new CDROutBus)
|
||||
|
||||
upStreamReq.io.clk4 := io.clk4
|
||||
downStreamReq.io.clk4 := io.clk4
|
||||
upStreamReq.io.dat := io.upStreamReqDat
|
||||
downStreamReq.io.dat := io.downStreamReqDat
|
||||
|
||||
io.upStreamRespdat := upStreamResp.io.dat
|
||||
io.downStreamRespdat := downStreamResp.io.dat
|
||||
|
||||
|
||||
|
||||
def IDLE = 0.U
|
||||
def UPSTREAM_RESP = 1.U
|
||||
def DOWNSTREAM_RESP = 2.U
|
||||
|
||||
val stateNext = Wire( UInt(2.W) )
|
||||
val stateCurr = RegNext(stateNext, 0.U)
|
||||
|
||||
stateNext := Mux1H(Seq(
|
||||
(stateCurr === IDLE) -> Mux(upStreamReq.io.latDat.fire, Mux(upStreamReq.io.latDat.bits.address(5,1) === io.localHost, UPSTREAM_RESP, DOWNSTREAM_RESP), Mux(downStreamReq.io.latDat.fire, UPSTREAM_RESP, IDLE) ),
|
||||
(stateCurr === UPSTREAM_RESP) -> Mux(upStreamResp.io.pkgDat.fire, IDLE, UPSTREAM_RESP ),
|
||||
(stateCurr === DOWNSTREAM_RESP) -> Mux(downStreamResp.io.pkgDat.fire, IDLE, DOWNSTREAM_RESP ),
|
||||
))
|
||||
|
||||
val upStreamReqReady = RegInit(false.B); upStreamReq.io.latDat.ready := upStreamReqReady
|
||||
val downStreamReqReady = RegInit(false.B); downStreamReq.io.latDat.ready := downStreamReqReady
|
||||
|
||||
val upStreamRespValid = RegInit(false.B); upStreamResp.io.pkgDat.valid := upStreamRespValid
|
||||
val upStreamRespInfo = Reg(new CDRData); upStreamResp.io.pkgDat.bits := upStreamRespInfo
|
||||
val downStreamRespValid = RegInit(false.B); downStreamResp.io.pkgDat.valid := downStreamRespValid
|
||||
val downStreamRespInfo = Reg(new CDRData); downStreamResp.io.pkgDat.bits := downStreamRespInfo
|
||||
|
||||
val registersRD = Wire(UInt(32.W))
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait StatusControl{ this: BackBoardSlvBase =>
|
||||
|
||||
when( upStreamResp.io.pkgDat.fire ){
|
||||
upStreamRespValid := false.B
|
||||
} .elsewhen( downStreamResp.io.pkgDat.fire ){
|
||||
downStreamRespValid := false.B
|
||||
}.elsewhen( upStreamReq.io.latDat.fire ){
|
||||
upStreamReqReady := false.B
|
||||
|
||||
when( upStreamReq.io.latDat.bits.address(5,1) === io.localHost ){
|
||||
upStreamRespValid := true.B
|
||||
upStreamRespInfo.address := upStreamReq.io.latDat.bits.address
|
||||
upStreamRespInfo.register := upStreamReq.io.latDat.bits.register
|
||||
upStreamRespInfo.data := Mux(upStreamReq.io.latDat.bits.address.extract(0) === 0.U, registersRD, 0.U )
|
||||
upStreamRespInfo.hash := 0.U
|
||||
|
||||
} .otherwise{
|
||||
downStreamRespValid := true.B
|
||||
downStreamRespInfo := upStreamReq.io.latDat.bits
|
||||
}
|
||||
|
||||
} .elsewhen( downStreamReq.io.latDat.fire ){
|
||||
downStreamReqReady := false.B
|
||||
|
||||
upStreamRespValid := true.B
|
||||
upStreamRespInfo := downStreamReq.io.latDat.bits
|
||||
} .elsewhen( downStreamReq.io.latDat.valid & ~downStreamReq.io.latDat.ready && stateCurr === IDLE ){
|
||||
downStreamReqReady := true.B
|
||||
} .elsewhen( upStreamReq.io.latDat.valid & ~upStreamReq.io.latDat.ready & ~downStreamReq.io.latDat.valid & stateCurr === IDLE ){
|
||||
upStreamReqReady := true.B
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class BackBoardSlv extends BackBoardSlvBase with StatusControl with LocalRegisters
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
|
||||
import freechips.rocketchip.util._
|
||||
|
||||
|
||||
class CDRData extends Bundle{
|
||||
val address = UInt(6.W)
|
||||
val register = UInt(8.W)
|
||||
val data = UInt(32.W)
|
||||
val hash = UInt(16.W)
|
||||
|
||||
def crcHash = 0.U
|
||||
def isHashPass = true.B
|
||||
|
||||
}
|
||||
|
||||
class CDR4MultiInIO() extends Bundle{
|
||||
val dat = Input(Bool())
|
||||
val clk4 = Input(Bool())
|
||||
|
||||
val latDat = Decoupled(new CDRData)
|
||||
}
|
||||
|
||||
|
||||
|
||||
class CDR4MultiIn() extends Module{
|
||||
val io: CDR4MultiInIO = IO(new CDR4MultiInIO())
|
||||
|
||||
val latValidSet = Wire(Bool())
|
||||
|
||||
val latValidSetAsync = ShiftRegister( latValidSet, 2, false.B, true.B )
|
||||
val latValidReset = RegNext(latValidSetAsync, false.B)
|
||||
|
||||
val transInfo = Wire(new CDRData)
|
||||
|
||||
withClockAndReset( io.clk4.asClock, reset ){
|
||||
val latValidSetReg = RegInit(false.B); latValidSet := latValidSetReg
|
||||
val latValidResetAsync = ShiftRegister(latValidReset, 2, false.B, true.B)
|
||||
|
||||
val shiftDat = RegInit( 0.U( ((1+6+8+32+16)*4+2).W ) )
|
||||
|
||||
|
||||
transInfo :=
|
||||
Cat(
|
||||
( 0 until (6+8+32+16) ).map{ i => shiftDat( 4*(i+1) + 1 ) }
|
||||
).asTypeOf(new CDRData)
|
||||
|
||||
|
||||
when( latValidSetReg & latValidResetAsync ){
|
||||
shiftDat := 0.U
|
||||
latValidSetReg := false.B
|
||||
} .elsewhen( shiftDat.extract(0) =/= 1.U ){
|
||||
shiftDat := Cat(io.dat, shiftDat( ((1+6+8+32+16)*4+2)-1, 1) )
|
||||
} .elsewhen( shiftDat.extract(0) === 1.U ){
|
||||
latValidSetReg := true.B
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
val latDatValid = RegInit(false.B)
|
||||
val latDatInfo = Reg(new CDRData)
|
||||
|
||||
when( io.latDat.fire ){
|
||||
latDatValid := false.B
|
||||
} .elsewhen( latValidSetAsync & ~latValidReset){
|
||||
latDatValid := true.B
|
||||
latDatInfo := transInfo
|
||||
}
|
||||
|
||||
io.latDat.valid := latDatValid
|
||||
io.latDat.bits := latDatInfo
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
class CDROutBusIO() extends Bundle{
|
||||
val pkgDat = Flipped(Decoupled(new CDRData))
|
||||
val dat = Output(Bool())
|
||||
|
||||
}
|
||||
|
||||
class CDROutBus extends Module{
|
||||
val io: CDROutBusIO = IO(new CDROutBusIO)
|
||||
|
||||
val isBusy = RegInit(false.B)
|
||||
io.pkgDat.ready := ~isBusy
|
||||
|
||||
val address = Reg(UInt(6.W))
|
||||
val register = Reg(UInt(8.W))
|
||||
val data = Reg(UInt(32.W))
|
||||
val hash = Reg(UInt(16.W))
|
||||
|
||||
val cnt = RegInit( 0.U(7.W) )
|
||||
|
||||
|
||||
when( cnt === (1+6+8+32+16).U ){
|
||||
isBusy := false.B
|
||||
} .elsewhen( io.pkgDat.fire ){
|
||||
isBusy := true.B
|
||||
|
||||
address := io.pkgDat.bits.address
|
||||
register := io.pkgDat.bits.register
|
||||
data := io.pkgDat.bits.data
|
||||
|
||||
}
|
||||
|
||||
when(io.pkgDat.fire){
|
||||
cnt := 0.U
|
||||
} .elsewhen( isBusy ){
|
||||
cnt := cnt + 1.U
|
||||
}
|
||||
|
||||
|
||||
|
||||
when( cnt === 1.U ){
|
||||
io.dat := true.B
|
||||
} .elsewhen( cnt >= (1 + 1).U && cnt < (6 + 1 + 1).U ){
|
||||
io.dat := address(5)
|
||||
address := address << 1
|
||||
} .elsewhen( cnt >= (1 + 1 + 6).U && cnt < (8 + 1+ 1 + 6).U ){
|
||||
io.dat := register(7)
|
||||
register := register << 1
|
||||
} .elsewhen( cnt >= (1 + 1 + 6 + 8).U && cnt < (32 + 1 + 1 + 6 + 8).U ){
|
||||
io.dat := data(31)
|
||||
data := data << 1
|
||||
} .elsewhen( cnt >= (1 + 1 + 6 + 8 + 32).U && cnt < (16 + 1 + 1 + 6 + 8 + 32).U ){
|
||||
io.dat := hash(15)
|
||||
hash := hash << 1
|
||||
} .otherwise{
|
||||
io.dat := false.B
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,649 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.interrupts._
|
||||
|
||||
import freechips.rocketchip.tile._
|
||||
|
||||
class RocCC2CDRInIO extends Bundle{
|
||||
val overCLK = Bool()
|
||||
val dDatIn = Bool()
|
||||
val uDatIn = Bool()
|
||||
|
||||
val isLast = Bool()
|
||||
}
|
||||
|
||||
class RocCC2CDROutIO extends Bundle{
|
||||
val dDatOut = Bool()
|
||||
val uDatOut = Bool()
|
||||
|
||||
val isOnline = Bool()
|
||||
}
|
||||
|
||||
class RoCC2CDRIO extends Bundle{
|
||||
val overCLK = Input(Bool())
|
||||
val dDatIn = Input(Bool())
|
||||
val dDatOut = Output(Bool())
|
||||
val uDatIn = Input(Bool())
|
||||
val uDatOut = Output(Bool())
|
||||
|
||||
val isOnline = Output(Bool())
|
||||
val isLast = Input(Bool())
|
||||
}
|
||||
|
||||
|
||||
|
||||
class RoCC2CDR()(implicit p: Parameters) extends LazyModule {
|
||||
val opcodes: OpcodeSet = OpcodeSet.custom0
|
||||
val roccCSRs: Seq[CustomCSR] = Nil
|
||||
lazy val module: RoCC2CDRImpl = new RoCC2CDRImpl(this)
|
||||
}
|
||||
|
||||
|
||||
|
||||
abstract class RoCC2CDRImplBase(outer: RoCC2CDR)(implicit p: Parameters) extends LazyModuleImp(outer) {
|
||||
val io = IO(new RoCCIO(0, 0))
|
||||
|
||||
// val cdrio: RoCC2CDRIO = IO(new RoCC2CDRIO)
|
||||
val cdrInio = IO(Input(new RocCC2CDRInIO))
|
||||
val cdrOutio = IO(Output(new RocCC2CDROutIO))
|
||||
|
||||
val CDRIn = for( i <- 0 until 2 ) yield { Module(new CDRIn) }
|
||||
when(true.B){
|
||||
print("Warning!!! New Code has not been reviewed!\n")
|
||||
}
|
||||
|
||||
CDRIn(0).io.serDat := cdrInio.dDatIn
|
||||
CDRIn(1).io.serDat := cdrInio.uDatIn
|
||||
|
||||
CDRIn(0).overCLK := cdrInio.overCLK
|
||||
CDRIn(1).overCLK := cdrInio.overCLK
|
||||
|
||||
|
||||
|
||||
val CDROut = for( i <- 0 until 2 ) yield { Module(new CDROut) }
|
||||
|
||||
cdrOutio.dDatOut := CDROut(0).io.serDat
|
||||
cdrOutio.uDatOut := CDROut(1).io.serDat
|
||||
|
||||
val txFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
|
||||
val rxFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
|
||||
|
||||
val isTLWriteSoftReset = for( i <- 0 until 4 ) yield { Wire(Bool()) }
|
||||
val isTLReadStatus = Wire( Bool() )
|
||||
|
||||
val txLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
|
||||
val rxLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
|
||||
|
||||
val wdata = Wire(UInt(32.W))
|
||||
|
||||
val isTLReadRxFifoBypassTx = for( i <- 0 until 4 ) yield { Wire(Bool()) } //0 rx0->tx0, 1 rx0->tx1, 2 rx1 -> tx0, 3 rx1 ->tx1
|
||||
}
|
||||
|
||||
|
||||
trait RoCC2CDRImplTx{ this: RoCC2CDRImplBase =>
|
||||
|
||||
|
||||
val isTLWriteTxLen = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
val isTLWriteTxFifo = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
|
||||
|
||||
val isTxFifoRelease = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
val txLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
|
||||
val isTxBusy = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isTxFull = for( i <- 0 until 2 ) yield { ~txFifo(i).io.enq.ready }
|
||||
val intTxFifoFull = for( i <- 0 until 2 ) yield { ~RegNext(isTxFull(i), false.B) & isTxFull(i) }
|
||||
val intTxFinish = for( i <- 0 until 2 ) yield { CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast }
|
||||
val intTxEnd = for( i <- 0 until 2 ) yield { ShiftRegister( intTxFinish(i), 6, false.B, true.B) }
|
||||
|
||||
val intTxFifoDeq = for( i <- 0 until 2 ) yield { txFifo(i).io.deq.fire }
|
||||
|
||||
val txCnt = for( i <- 0 until 2 ) yield { Reg(UInt(2.W)) }
|
||||
val txData = for( i <- 0 until 2 ) yield { Reg(UInt(32.W)) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
when( txFifo(i).io.deq.fire ){ //txCnt(i) === 3.U
|
||||
txData(i) := txFifo(i).io.deq.bits
|
||||
when( isTxBusy(i) ){
|
||||
assert(CDROut(i).io.axis.fire)
|
||||
}
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txData(i) := txData(i) << 8
|
||||
}
|
||||
|
||||
txFifo(i).io.deq.ready :=
|
||||
isTxFifoRelease(i) & Mux( isTxBusy(i), CDROut(i).io.axis.fire & txCnt(i) === 3.U, true.B )
|
||||
|
||||
txFifo(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
CDROut(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
|
||||
CDROut(i).io.axis.bits.tdata := txData(i).head(8)
|
||||
CDROut(i).io.axis.bits.tlast := ~txFifo(i).io.deq.valid & txCnt(i) === 3.U
|
||||
CDROut(i).io.axis.bits.tuser := false.B
|
||||
CDROut(i).io.axis.valid := isTxBusy(i)
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(i) ){
|
||||
isTxBusy(i) := false.B
|
||||
}.elsewhen( txFifo(i).io.deq.fire & ~isTxBusy(i) ){
|
||||
isTxBusy(i) := true.B
|
||||
} .elsewhen( CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast ){
|
||||
isTxBusy(i) := false.B
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
txCnt(i) := 0.U
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txCnt(i) := txCnt(i) + 1.U
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteTxLen(i) ){
|
||||
txLen(i) := wdata
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txLen(i) := txLen(i) - 1.U
|
||||
}
|
||||
|
||||
txFifo(i).io.enq.bits := Mux1H(Seq(
|
||||
isTLWriteTxFifo(i) -> wdata,
|
||||
isTLReadRxFifoBypassTx(0+i) -> rxFifo(0).io.deq.bits,
|
||||
isTLReadRxFifoBypassTx(2+i) -> rxFifo(1).io.deq.bits,
|
||||
))
|
||||
|
||||
|
||||
|
||||
//0 rx0->tx0, 1 rx0->tx1, 2 rx1 -> tx0, 3 rx1 ->tx1
|
||||
|
||||
txFifo(i).io.enq.valid :=
|
||||
txLen(i) =/= 0.U & (
|
||||
isTLWriteTxFifo(i) |
|
||||
isTLReadRxFifoBypassTx(0+i) |
|
||||
isTLReadRxFifoBypassTx(2+i)
|
||||
)
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
txLeft(i) := 0.U
|
||||
} .elsewhen( txFifo(i).io.enq.fire & txFifo(i).io.deq.fire ){
|
||||
txLeft(i) := txLeft(i)
|
||||
} .elsewhen( txFifo(i).io.enq.fire ){
|
||||
txLeft(i) := txLeft(i) + 1.U
|
||||
} .elsewhen( txFifo(i).io.deq.fire ){
|
||||
txLeft(i) := txLeft(i) - 1.U
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait RoCC2CDRImplRx{ this: RoCC2CDRImplBase =>
|
||||
|
||||
val isTLReadRxLen = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLReadRxFifo = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val rxLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
|
||||
val isRxValid = for( i <- 0 until 2 ) yield { rxFifo(i).io.deq.valid }
|
||||
val isRxError = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isAxisEnd = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isRxEnd = for( i <- 0 until 2 ) yield { isAxisEnd(i) & ~rxFifo(i).io.deq.valid }
|
||||
val intRxError = for( i <- 0 until 2 ) yield { ~RegNext(isRxError(i), false.B) & isRxError(i) }
|
||||
val intRxStart = for( i <- 0 until 2 ) yield { rxLen(i) === 0.U & CDRIn(i).io.axis.fire }
|
||||
val intRxEnd = for( i <- 0 until 2 ) yield { ~RegNext(isRxEnd(i), false.B) & isRxEnd(i) }
|
||||
val intRxFifoEnq = for( i <- 0 until 2 ) yield { rxFifo(i).io.enq.fire }
|
||||
val rxCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(2.W)) }
|
||||
val rxData = for( i <- 0 until 2 ) yield { Reg(UInt(24.W)) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
isAxisEnd(i) := false.B
|
||||
} .elsewhen( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast ){
|
||||
isAxisEnd(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxCnt(i) := 0.U
|
||||
} .elsewhen( CDRIn(i).io.axis.fire ){
|
||||
rxCnt(i) := rxCnt(i) + 1.U
|
||||
rxData(i) := Cat( rxData(i), CDRIn(i).io.axis.bits.tdata )
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxLen(i) := 0.U
|
||||
} .elsewhen( CDRIn(i).io.axis.fire ){
|
||||
rxLen(i) := rxLen(i) + 1.U
|
||||
}
|
||||
|
||||
rxFifo(i).io.enq.valid := CDRIn(i).io.axis.fire & rxCnt(i) === 3.U
|
||||
rxFifo(i).io.enq.bits := Cat( rxData(i)(23, 0) , CDRIn(i).io.axis.bits.tdata )
|
||||
|
||||
assert( ~(( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast) & rxCnt(i) =/= 3.U), "Assert Failed! Rx must 4-byte Align!" )
|
||||
|
||||
CDRIn(i).io.axis.ready := true.B
|
||||
|
||||
rxFifo(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
CDRIn(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
|
||||
rxFifo(i).io.deq.ready := isTLReadRxFifo(i)
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
isRxError(i) := false.B
|
||||
} .elsewhen( rxFifo(i).io.enq.valid & ~rxFifo(i).io.enq.ready ){
|
||||
isRxError(i) := true.B
|
||||
printf(s"Warning, RxFifo$i Overflow!\n")
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxLeft(i) := 0.U
|
||||
} .elsewhen( rxFifo(i).io.enq.fire & rxFifo(i).io.deq.fire ){
|
||||
rxLeft(i) := rxLeft(i)
|
||||
} .elsewhen( rxFifo(i).io.enq.fire ){
|
||||
rxLeft(i) := rxLeft(i) + 1.U
|
||||
} .elsewhen( rxFifo(i).io.deq.fire ){
|
||||
rxLeft(i) := rxLeft(i) - 1.U
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait RoCC2CDRImplIsLast{ this: RoCC2CDRImplBase =>
|
||||
cdrOutio.isOnline := false.B
|
||||
val isReadIsLast = Wire(Bool())
|
||||
|
||||
}
|
||||
|
||||
trait RoCC2CDRImplUserCRC{ this: RoCC2CDRImplBase =>
|
||||
val isTLWriteTxFifo: Seq[Bool]
|
||||
val isTLReadRxFifo: Seq[Bool]
|
||||
|
||||
val isTLReadTxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLReadRxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
|
||||
val txCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
val rxCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
txCrc(i).io.enq.valid := isTLWriteTxFifo(i)
|
||||
txCrc(i).io.enq.bits := wdata
|
||||
|
||||
rxCrc(i).io.enq.valid := isTLReadRxFifo(i)
|
||||
rxCrc(i).io.enq.bits := rxFifo(i).io.deq.bits
|
||||
|
||||
txCrc(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
rxCrc(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait RoCC2CDRImplLimitTimmer{ this: RoCC2CDRImplBase =>
|
||||
val intRxStart: Seq[Bool]
|
||||
val isTLWriteSoftReset: Seq[Bool]
|
||||
val isTxFifoRelease: Seq[Bool]
|
||||
|
||||
val isTLWriteLimitTimerAim = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLWriteLimitTxPair = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val limitTimerCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
|
||||
val limitTimerAim = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
|
||||
val isLimitTimerTrigger = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val txPairSel = for( i <- 0 until 2 ) yield { RegInit((i.U)(2.W)) }
|
||||
|
||||
for( i <- 0 until 2 ){
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
limitTimerCnt(i) := 0.U
|
||||
} .elsewhen( limitTimerCnt(i) =/= limitTimerAim(i) ){
|
||||
when( isLimitTimerTrigger(i) ){
|
||||
limitTimerCnt(i) := limitTimerCnt(i) + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
when( isTLWriteLimitTimerAim(i) ){
|
||||
limitTimerAim(i) := wdata
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
isLimitTimerTrigger(i) := false.B
|
||||
} .elsewhen( intRxStart(i) ){
|
||||
isLimitTimerTrigger(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
txPairSel(i) := i.U
|
||||
} .elsewhen( isTLWriteLimitTxPair(i) ){
|
||||
txPairSel(i) := wdata
|
||||
}
|
||||
|
||||
|
||||
isTxFifoRelease(i) := ( 0 until 2).map{ lmt =>
|
||||
((txPairSel(lmt) =/= i.U) | (limitTimerCnt(lmt) === limitTimerAim(lmt)))
|
||||
}.reduce(_&_)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
trait RoCC2CDRImplOutTimmer{ this: RoCC2CDRImplBase =>
|
||||
val isTxBusy: Seq[Bool]
|
||||
|
||||
val timeOutCnt = for( _ <- 0 until 2 ) yield { RegInit(0.U(32.W)) }
|
||||
val isTLClearTimeOut = for( _ <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLReadTimeOut = for( _ <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val isTxClearTimeOut = for( i <- 0 until 2 ) yield { ~RegNext(isTxBusy(i)) & isTxBusy(i) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
when( isTLClearTimeOut(i) | isTxClearTimeOut(i) ){
|
||||
timeOutCnt(i) := 0.U
|
||||
} .otherwise{
|
||||
timeOutCnt(i) := timeOutCnt(i) + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class RoCC2CDRImpl(outer: RoCC2CDR)(implicit p: Parameters) extends RoCC2CDRImplBase(outer)
|
||||
with RoCC2CDRImplTx with RoCC2CDRImplRx
|
||||
with RoCC2CDRImplIsLast
|
||||
with RoCC2CDRImplUserCRC
|
||||
with RoCC2CDRImplLimitTimmer with RoCC2CDRImplOutTimmer
|
||||
{
|
||||
|
||||
|
||||
|
||||
io.mem.req.valid := false.B
|
||||
io.mem.req.bits := DontCare
|
||||
io.mem.s1_kill := false.B
|
||||
io.mem.s1_data := DontCare
|
||||
io.mem.s2_kill := false.B
|
||||
io.mem.keep_clock_enabled := false.B
|
||||
|
||||
io.fpu_req.valid := false.B
|
||||
io.fpu_req.bits := DontCare
|
||||
io.fpu_resp.ready := true.B
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
isTLWriteSoftReset(0) := io.cmd.fire & io.cmd.bits.inst.funct === 0.U
|
||||
isTLWriteTxLen(0) := io.cmd.fire & io.cmd.bits.inst.funct === 1.U
|
||||
isTLWriteTxFifo(0) := io.cmd.fire & io.cmd.bits.inst.funct === 2.U
|
||||
isTLReadTxCrc(0) := io.cmd.fire & io.cmd.bits.inst.funct === 3.U
|
||||
isTLClearTimeOut(0) := io.cmd.fire & io.cmd.bits.inst.funct === 4.U & io.cmd.bits.inst.xs1
|
||||
isTLReadTimeOut(0) := io.cmd.fire & io.cmd.bits.inst.funct === 4.U & io.cmd.bits.inst.xd
|
||||
|
||||
isTLWriteSoftReset(1) := io.cmd.fire & io.cmd.bits.inst.funct === 5.U
|
||||
isTLWriteTxLen(1) := io.cmd.fire & io.cmd.bits.inst.funct === 6.U
|
||||
isTLWriteTxFifo(1) := io.cmd.fire & io.cmd.bits.inst.funct === 7.U
|
||||
isTLReadTxCrc(1) := io.cmd.fire & io.cmd.bits.inst.funct === 8.U
|
||||
isTLClearTimeOut(1) := io.cmd.fire & io.cmd.bits.inst.funct === 9.U & io.cmd.bits.inst.xs1
|
||||
isTLReadTimeOut(1) := io.cmd.fire & io.cmd.bits.inst.funct === 9.U & io.cmd.bits.inst.xd
|
||||
|
||||
//0 rx0->tx0, 1 rx0->tx1, 2 rx1 -> tx0, 3 rx1 ->tx1
|
||||
isTLWriteSoftReset(2) := io.cmd.fire & io.cmd.bits.inst.funct === 10.U
|
||||
isTLReadRxLen(0) := io.cmd.fire & io.cmd.bits.inst.funct === 11.U
|
||||
isTLReadRxFifo(0) := io.cmd.fire & io.cmd.bits.inst.funct === 12.U
|
||||
isTLReadRxFifoBypassTx(0) := io.cmd.fire & io.cmd.bits.inst.funct === 13.U
|
||||
isTLReadRxFifoBypassTx(1) := io.cmd.fire & io.cmd.bits.inst.funct === 14.U
|
||||
isTLReadRxCrc(0) := io.cmd.fire & io.cmd.bits.inst.funct === 15.U
|
||||
isTLWriteLimitTimerAim(0) := io.cmd.fire & io.cmd.bits.inst.funct === 16.U
|
||||
isTLWriteLimitTxPair(0) := io.cmd.fire & io.cmd.bits.inst.funct === 17.U
|
||||
|
||||
isTLWriteSoftReset(3) := io.cmd.fire & io.cmd.bits.inst.funct === 18.U
|
||||
isTLReadRxLen(1) := io.cmd.fire & io.cmd.bits.inst.funct === 19.U
|
||||
isTLReadRxFifo(1) := io.cmd.fire & io.cmd.bits.inst.funct === 20.U
|
||||
isTLReadRxFifoBypassTx(2) := io.cmd.fire & io.cmd.bits.inst.funct === 21.U
|
||||
isTLReadRxFifoBypassTx(3) := io.cmd.fire & io.cmd.bits.inst.funct === 22.U
|
||||
isTLReadRxCrc(1) := io.cmd.fire & io.cmd.bits.inst.funct === 23.U
|
||||
isTLWriteLimitTimerAim(1) := io.cmd.fire & io.cmd.bits.inst.funct === 24.U
|
||||
isTLWriteLimitTxPair(1) := io.cmd.fire & io.cmd.bits.inst.funct === 25.U
|
||||
|
||||
isTLReadStatus := io.cmd.fire & io.cmd.bits.inst.funct === 26.U
|
||||
val isTLReadInterrupt = io.cmd.fire & io.cmd.bits.inst.funct === 27.U & io.cmd.bits.inst.xd
|
||||
val isTLClearInterrupt = io.cmd.fire & io.cmd.bits.inst.funct === 27.U & io.cmd.bits.inst.xs1
|
||||
val isTLWriteIntMask = io.cmd.fire & io.cmd.bits.inst.funct === 28.U
|
||||
isReadIsLast := io.cmd.fire & io.cmd.bits.inst.funct === 29.U
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
val interruptReg = RegInit(0.U(32.W))
|
||||
val interruptMask = RegEnable(wdata, 0.U(32.W), isTLWriteIntMask)
|
||||
|
||||
val statusRxStart = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val statusRxEnd = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val statusTxEnd = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
|
||||
for( i <- 0 until 2 ){
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
statusRxStart(i) := false.B
|
||||
} .elsewhen( intRxStart(i) ){
|
||||
statusRxStart(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
statusRxEnd(i) := false.B
|
||||
} .elsewhen( intRxEnd(i) ){
|
||||
statusRxEnd(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
statusTxEnd(i) := false.B
|
||||
} .elsewhen( intTxEnd(i) ){
|
||||
statusTxEnd(i) := true.B
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
when(true.B){
|
||||
interruptReg :=
|
||||
(
|
||||
(interruptReg & Mux( isTLClearInterrupt, ~wdata, "hFFFFFFFF".U)) | Cat(
|
||||
intTxEnd(1), intTxEnd(0),
|
||||
intRxError(1), intRxError(0),
|
||||
intRxStart(1), intRxStart(0),
|
||||
intRxEnd(1), intRxEnd(0),
|
||||
intTxFifoDeq(1), intTxFifoDeq(0),
|
||||
intRxFifoEnq(1), intRxFifoEnq(0)
|
||||
)
|
||||
) & interruptMask
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
io.interrupt :=
|
||||
( intTxEnd(1) & interruptMask.extract(11) ) |
|
||||
( intTxEnd(0) & interruptMask.extract(10) ) |
|
||||
( intRxError(1) & interruptMask.extract( 9) ) |
|
||||
( intRxError(0) & interruptMask.extract( 8) ) |
|
||||
( intRxStart(1) & interruptMask.extract( 7) ) |
|
||||
( intRxStart(0) & interruptMask.extract( 6) ) |
|
||||
( intRxEnd(1) & interruptMask.extract( 5) ) |
|
||||
( intRxEnd(0) & interruptMask.extract( 4) ) |
|
||||
( intTxFifoDeq(1) & interruptMask.extract( 3) ) |
|
||||
( intTxFifoDeq(0) & interruptMask.extract( 2) ) |
|
||||
( intRxFifoEnq(1) & interruptMask.extract( 1) ) |
|
||||
( intRxFifoEnq(0) & interruptMask.extract( 0) )
|
||||
|
||||
wdata := io.cmd.bits.rs1
|
||||
|
||||
val cmdInfo = RegEnable(io.cmd.bits, io.cmd.fire)
|
||||
val rdata = Reg(UInt(32.W))
|
||||
|
||||
|
||||
// val cmdReady = RegInit(true.B)
|
||||
val respValid = RegInit(false.B)
|
||||
|
||||
io.busy := respValid
|
||||
io.cmd.ready := ~respValid
|
||||
|
||||
io.resp.valid := respValid
|
||||
io.resp.bits.rd := cmdInfo.inst.rd
|
||||
|
||||
io.resp.bits.data := rdata
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
printf("Warning, no protection on tx rx fifo!\n")
|
||||
// MuxCase( true.B, Array(
|
||||
// ( io.cmd.bits.inst.funct === 2.U ) -> txFifo(0).io.enq.ready,
|
||||
// ( io.cmd.bits.inst.funct === 6.U ) -> txFifo(1).io.enq.ready,
|
||||
// ( bus.a.bits.address(7,0) === "h28".U ) -> rxFifo(0).io.deq.valid,
|
||||
// ( bus.a.bits.address(7,0) === "h48".U ) -> rxFifo(1).io.deq.valid,
|
||||
// ))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
when( isTLReadStatus ){
|
||||
rdata := Cat(
|
||||
txLeft(1), txLeft(0), rxLeft(1), rxLeft(0),
|
||||
isRxValid(1), isRxValid(0), isRxError(1), isRxError(0),
|
||||
statusRxStart(1), statusRxStart(0), statusRxEnd(1), statusRxEnd(0), statusTxEnd(1), statusTxEnd(0)
|
||||
)
|
||||
} .elsewhen(isTLReadRxLen(0) ){
|
||||
rdata := rxLen(0)
|
||||
} .elsewhen(isTLReadRxLen(1) ){
|
||||
rdata := rxLen(1)
|
||||
} .elsewhen(isTLReadRxFifo(0) | isTLReadRxFifoBypassTx(0) | isTLReadRxFifoBypassTx(1) ){
|
||||
rdata := rxFifo(0).io.deq.bits
|
||||
} .elsewhen(isTLReadRxFifo(1) | isTLReadRxFifoBypassTx(2) | isTLReadRxFifoBypassTx(3) ){
|
||||
rdata := rxFifo(1).io.deq.bits
|
||||
} .elsewhen(isReadIsLast){
|
||||
rdata := cdrInio.isLast
|
||||
} .elsewhen(isTLReadTxCrc(0)){
|
||||
rdata := txCrc(0).io.crc
|
||||
} .elsewhen(isTLReadTxCrc(1)){
|
||||
rdata := txCrc(1).io.crc
|
||||
} .elsewhen(isTLReadRxCrc(0)){
|
||||
rdata := rxCrc(0).io.crc
|
||||
} .elsewhen(isTLReadRxCrc(1)){
|
||||
rdata := rxCrc(1).io.crc
|
||||
} .elsewhen(isTLReadInterrupt){
|
||||
rdata := interruptReg
|
||||
} .elsewhen(isTLReadTimeOut(0)){
|
||||
rdata := timeOutCnt(0)
|
||||
} .elsewhen(isTLReadTimeOut(1)){
|
||||
rdata := timeOutCnt(1)
|
||||
}
|
||||
|
||||
|
||||
when( io.resp.fire ){ //允许连续触发
|
||||
respValid := false.B
|
||||
} .elsewhen( isTLReadStatus ){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadRxLen(0) ){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadRxLen(1) ){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadRxFifo(0) | isTLReadRxFifoBypassTx(0) | isTLReadRxFifoBypassTx(1) ){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadRxFifo(1) | isTLReadRxFifoBypassTx(2) | isTLReadRxFifoBypassTx(3) ){
|
||||
respValid := true.B
|
||||
} .elsewhen(isReadIsLast){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadTxCrc(0)){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadTxCrc(1)){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadRxCrc(0)){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadRxCrc(1)){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadInterrupt){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadTimeOut(0)){
|
||||
respValid := true.B
|
||||
} .elsewhen(isTLReadTimeOut(1)){
|
||||
respValid := true.B
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait HasLazyRoCC2CDR { this: BaseTile =>
|
||||
val roccs = LazyModule(new RoCC2CDR())
|
||||
|
||||
val roccCSRs = Seq(roccs.roccCSRs) // the set of custom CSRs requested by all roccs
|
||||
}
|
||||
|
||||
trait HasLazyRoCC2CDRModule extends HasCoreParameters { this: RocketTileModuleImp with HasFpuOpt =>
|
||||
|
||||
// val (respArb, cmdRouter) = {
|
||||
// val respArb = Module(new RRArbiter(new RoCCResponse()(outer.p), outer.roccs.size))
|
||||
val cmdRouter = Module(new Queue( new RoCCCommand, 2, false, true ))//Module(new RoccCommandRouter( Seq(outer.roccs.opcodes) )(outer.p))
|
||||
|
||||
// outer.roccs.module.io.ptw ++=: ptwPorts
|
||||
outer.roccs.module.io.cmd <> cmdRouter.io.deq
|
||||
// val dcIF = Module(new SimpleHellaCacheIF()(outer.p))
|
||||
// dcIF.io.requestor <> outer.roccs.module.io.mem
|
||||
// dcachePorts += dcIF.io.cache
|
||||
//respArb.io.in(0) <> Queue(outer.roccs.module.io.resp)
|
||||
|
||||
|
||||
fpuOpt foreach { fpu =>
|
||||
fpu.io.cp_req.valid := false.B
|
||||
fpu.io.cp_resp.ready := false.B
|
||||
}
|
||||
|
||||
// (Some(respArb), Some(cmdRouter))
|
||||
// }
|
||||
|
||||
// val roccCSRIOs = Seq(outer.roccs.module.io.csrs)
|
||||
|
||||
// (core.io.rocc.csrs zip roccCSRIOs.flatten).foreach { t => t._2 := t._1 }
|
||||
|
||||
val cdrInio = IO(Input(new RocCC2CDRInIO))
|
||||
val cdrOutio = IO(Output(new RocCC2CDROutIO))
|
||||
|
||||
// val cdrio: RoCC2CDRIO = IO(new RoCC2CDRIO)
|
||||
// dontTouch(cdrio)
|
||||
|
||||
|
||||
cdrInio <> outer.roccs.module.cdrInio
|
||||
cdrOutio <> outer.roccs.module.cdrOutio
|
||||
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
class CDR_Master_Interface_Bundle extends CDRData{
|
||||
val op = UInt(2.W)
|
||||
}
|
||||
|
||||
class SpiSlvIO extends Bundle{
|
||||
val CS = Input(Bool())
|
||||
val MISO = Output(Bool())
|
||||
val MOSI = Input(Bool())
|
||||
val SCK = Input(Bool())
|
||||
|
||||
val clk4 = Input(Bool())
|
||||
|
||||
val CDRIn = Flipped(Decoupled(new CDRData))
|
||||
val CDROut = Decoupled(new CDRData)
|
||||
|
||||
}
|
||||
|
||||
class SpiSlv extends Module{
|
||||
val io: SpiSlvIO = IO(new SpiSlvIO)
|
||||
|
||||
val CDROutValidSet = Wire(Bool())
|
||||
val CDROutValidSetAsync = ShiftRegister(CDROutValidSet, 2, false.B, true.B)
|
||||
val CDROutValidReset = RegNext(CDROutValidSetAsync, false.B)
|
||||
|
||||
// val CDRInValidSet = RegInit(false.B)
|
||||
val CDRInValidReset = Wire(Bool())
|
||||
val CDRInValidResetAsync = ShiftRegister( CDRInValidReset, 2, false.B, true.B)
|
||||
|
||||
val cent = Wire(new CDR_Master_Interface_Bundle)
|
||||
withClockAndReset( io.clk4.asClock, reset ){
|
||||
val centReg = RegInit(0.U.asTypeOf(new CDR_Master_Interface_Bundle)); cent := centReg
|
||||
val sckShift = ShiftRegisters( io.SCK, 3, false.B, true.B )
|
||||
val csShift = ShiftRegisters( io.CS, 3, true.B, true.B )
|
||||
val mosiShift = ShiftRegisters( io.MOSI, 2, true.B, true.B )
|
||||
|
||||
|
||||
val CDROutValidSetReg = RegInit(false.B); CDROutValidSet := CDROutValidSetReg
|
||||
val CDROutValidResetAsync = ShiftRegister( CDROutValidReset, 2, false.B, true.B )
|
||||
|
||||
val CDRInValidSetAsync = ShiftRegister( io.CDRIn.valid , 2, false.B, true.B )
|
||||
val CDRInValidResetReg = RegNext(CDRInValidSetAsync & csShift(1) & ~CDROutValidSetReg, false.B); CDRInValidReset := CDRInValidResetReg
|
||||
|
||||
when( CDROutValidSetReg & CDROutValidResetAsync ){
|
||||
CDROutValidSetReg := false.B
|
||||
centReg.op := 1.U
|
||||
} .elsewhen( ~csShift(2) & csShift(1) ){
|
||||
CDROutValidSetReg := true.B
|
||||
}
|
||||
|
||||
io.MISO := centReg.asUInt.extract( 6+8+32+2+16-1 )
|
||||
|
||||
val sckPosedge = ~sckShift(2) & sckShift(1)
|
||||
val sckNegedge = sckShift(2) & ~sckShift(1)
|
||||
|
||||
when( ~csShift(1) ){
|
||||
when( sckPosedge ){
|
||||
centReg := Cat(centReg.asUInt( 6+8+32+2+16-2, 0 ), mosiShift(1)).asTypeOf(new CDR_Master_Interface_Bundle)
|
||||
}
|
||||
} .otherwise{
|
||||
when( CDRInValidSetAsync & ~CDROutValidSetReg ){
|
||||
centReg.address := io.CDRIn.bits.address
|
||||
centReg.register := io.CDRIn.bits.register
|
||||
centReg.data := io.CDRIn.bits.data
|
||||
centReg.op := 0.U
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val CDROutValid = RegInit(false.B); io.CDROut.valid := CDROutValid
|
||||
val CDROutInfo = Reg(new CDRData); io.CDROut.bits := CDROutInfo
|
||||
|
||||
when( io.CDROut.fire ){
|
||||
CDROutValid := false.B
|
||||
} .elsewhen( CDROutValidSet & ~CDROutValidSetAsync ){
|
||||
CDROutValid := true.B
|
||||
CDROutInfo := cent
|
||||
}
|
||||
|
||||
io.CDRIn.ready := CDRInValidResetAsync
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,456 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.interrupts._
|
||||
|
||||
|
||||
class TL2CDR(implicit p: Parameters) extends LazyModule{
|
||||
val device = new SimpleDevice("TL_CDR", Nil)
|
||||
val node = TLManagerNode(Seq(TLSlavePortParameters.v1(
|
||||
managers = Seq(
|
||||
TLSlaveParameters.v2(
|
||||
address = Seq(AddressSet(0x10000000L, 0xffffL)), //64K
|
||||
name = Some("TL_CDR"),
|
||||
regionType = RegionType.VOLATILE,
|
||||
resources = device.reg,
|
||||
executable = false,
|
||||
fifoId = Some(0),
|
||||
supports = TLMasterToSlaveTransferSizes(
|
||||
get = TransferSizes(1, 32/8),
|
||||
putFull = TransferSizes(1, 32/8),
|
||||
putPartial = TransferSizes(1, 32/8),
|
||||
),
|
||||
)
|
||||
),
|
||||
beatBytes = 32/8)))
|
||||
|
||||
val int_node = IntSourceNode(IntSourcePortSimple(num = 12, resources = device.int))
|
||||
|
||||
lazy val module: TL2CDRImpl = new TL2CDRImpl(this)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
abstract class TL2CDRImplBase(outer: TL2CDR)(implicit p: Parameters) extends LazyModuleImp(outer) {
|
||||
class TLCDRIO extends Bundle{
|
||||
val overCLK = Input(Bool())
|
||||
val dDatIn = Input(Bool())
|
||||
val dDatOut = Output(Bool())
|
||||
val uDatIn = Input(Bool())
|
||||
val uDatOut = Output(Bool())
|
||||
|
||||
val isOnline = Output(Bool())
|
||||
val isLast = Input(Bool())
|
||||
}
|
||||
|
||||
val io: TLCDRIO = IO(new TLCDRIO)
|
||||
|
||||
val ( int, _ ) = outer.int_node.out(0)
|
||||
val ( bus, edge ) = outer.node.in.head
|
||||
|
||||
val CDRIn = for( i <- 0 until 2 ) yield { Module(new CDRIn) }
|
||||
when(true.B){
|
||||
print("Warning!!! New Code has not been reviewed!\n")
|
||||
}
|
||||
|
||||
CDRIn(0).io.serDat := io.dDatIn
|
||||
CDRIn(1).io.serDat := io.uDatIn
|
||||
|
||||
CDRIn(0).overCLK := io.overCLK
|
||||
CDRIn(1).overCLK := io.overCLK
|
||||
|
||||
val CDROut = for( i <- 0 until 2 ) yield { Module(new CDROut) }
|
||||
|
||||
io.dDatOut := CDROut(0).io.serDat
|
||||
io.uDatOut := CDROut(1).io.serDat
|
||||
|
||||
val txFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
|
||||
val rxFifo = for( i <- 0 until 2 ) yield { Module(new Queue(UInt(32.W), 16)) }
|
||||
|
||||
val isTLWriteSoftReset = for( i <- 0 until 4 ) yield { Wire(Bool()) }
|
||||
val isTLReadStatus = Wire( Bool() )
|
||||
|
||||
val txLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
|
||||
val rxLeft = for( i <- 0 until 2 ) yield { RegInit(0.U(5.W)) }
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait TL2CDRImplTx{ this: TL2CDRImplBase =>
|
||||
|
||||
|
||||
val isTLWriteTxLen = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
val isTLWriteTxFifo = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
|
||||
|
||||
val isTxFifoRelease = for( i <- 0 until 2 ) yield { Wire( Bool()) }
|
||||
val txLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
|
||||
val isTxBusy = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isTxFull = for( i <- 0 until 2 ) yield { ~txFifo(i).io.enq.ready }
|
||||
val intTxFifoFull = for( i <- 0 until 2 ) yield { ~RegNext(isTxFull(i), false.B) & isTxFull(i) }
|
||||
val intTxFinish = for( i <- 0 until 2 ) yield { CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast }
|
||||
val intTxEnd = for( i <- 0 until 2 ) yield { ShiftRegister( intTxFinish(i), 6, false.B, true.B) }
|
||||
|
||||
val intTxFifoDeq = for( i <- 0 until 2 ) yield { txFifo(i).io.deq.fire }
|
||||
// println("Warning, TxEnd no confident\n")
|
||||
|
||||
|
||||
val txCnt = for( i <- 0 until 2 ) yield { Reg(UInt(2.W)) }
|
||||
val txData = for( i <- 0 until 2 ) yield { Reg(UInt(32.W)) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
when( txFifo(i).io.deq.fire ){ //txCnt(i) === 3.U
|
||||
txData(i) := txFifo(i).io.deq.bits
|
||||
when( isTxBusy(i) ){
|
||||
assert(CDROut(i).io.axis.fire)
|
||||
}
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txData(i) := txData(i) << 8
|
||||
}
|
||||
|
||||
txFifo(i).io.deq.ready :=
|
||||
isTxFifoRelease(i) & Mux( isTxBusy(i), CDROut(i).io.axis.fire & txCnt(i) === 3.U, true.B )
|
||||
|
||||
txFifo(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
CDROut(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
|
||||
CDROut(i).io.axis.bits.tdata := txData(i).head(8)
|
||||
CDROut(i).io.axis.bits.tlast := ~txFifo(i).io.deq.valid & txCnt(i) === 3.U
|
||||
CDROut(i).io.axis.bits.tuser := false.B
|
||||
CDROut(i).io.axis.valid := isTxBusy(i)
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(i) ){
|
||||
isTxBusy(i) := false.B
|
||||
}.elsewhen( txFifo(i).io.deq.fire & ~isTxBusy(i) ){
|
||||
isTxBusy(i) := true.B
|
||||
} .elsewhen( CDROut(i).io.axis.fire & CDROut(i).io.axis.bits.tlast ){
|
||||
isTxBusy(i) := false.B
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
txCnt(i) := 0.U
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txCnt(i) := txCnt(i) + 1.U
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteTxLen(i) ){
|
||||
txLen(i) := bus.a.bits.data
|
||||
} .elsewhen( CDROut(i).io.axis.fire ){
|
||||
txLen(i) := txLen(i) - 1.U
|
||||
}
|
||||
|
||||
txFifo(i).io.enq.bits := bus.a.bits.data
|
||||
txFifo(i).io.enq.valid := isTLWriteTxFifo(i) & txLen(i) =/= 0.U
|
||||
|
||||
when( isTLWriteSoftReset(0+i) ){
|
||||
txLeft(i) := 0.U
|
||||
} .elsewhen( txFifo(i).io.enq.fire & txFifo(i).io.deq.fire ){
|
||||
txLeft(i) := txLeft(i)
|
||||
} .elsewhen( txFifo(i).io.enq.fire ){
|
||||
txLeft(i) := txLeft(i) + 1.U
|
||||
} .elsewhen( txFifo(i).io.deq.fire ){
|
||||
txLeft(i) := txLeft(i) - 1.U
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait TL2CDRImplRx{ this: TL2CDRImplBase =>
|
||||
|
||||
val isTLReadRxLen = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLReadRxFifo = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val rxLen = for( i <- 0 until 2 ) yield { RegInit(0.U(12.W)) }
|
||||
val isRxValid = for( i <- 0 until 2 ) yield { rxFifo(i).io.deq.valid }
|
||||
val isRxError = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isAxisEnd = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val isRxEnd = for( i <- 0 until 2 ) yield { isAxisEnd(i) & ~rxFifo(i).io.deq.valid }
|
||||
val intRxError = for( i <- 0 until 2 ) yield { ~RegNext(isRxError(i), false.B) & isRxError(i) }
|
||||
val intRxStart = for( i <- 0 until 2 ) yield { rxLen(i) === 0.U & CDRIn(i).io.axis.fire }
|
||||
val intRxEnd = for( i <- 0 until 2 ) yield { ~RegNext(isRxEnd(i), false.B) & isRxEnd(i) }
|
||||
val intRxFifoEnq = for( i <- 0 until 2 ) yield { rxFifo(i).io.enq.fire }
|
||||
val rxCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(2.W)) }
|
||||
val rxData = for( i <- 0 until 2 ) yield { Reg(UInt(24.W)) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
isAxisEnd(i) := false.B
|
||||
} .elsewhen( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast ){
|
||||
isAxisEnd(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxCnt(i) := 0.U
|
||||
} .elsewhen( CDRIn(i).io.axis.fire ){
|
||||
rxCnt(i) := rxCnt(i) + 1.U
|
||||
rxData(i) := Cat( rxData(i), CDRIn(i).io.axis.bits.tdata )
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxLen(i) := 0.U
|
||||
} .elsewhen( CDRIn(i).io.axis.fire ){
|
||||
rxLen(i) := rxLen(i) + 1.U
|
||||
}
|
||||
|
||||
rxFifo(i).io.enq.valid := CDRIn(i).io.axis.fire & rxCnt(i) === 3.U
|
||||
rxFifo(i).io.enq.bits := Cat( rxData(i)(23, 0) , CDRIn(i).io.axis.bits.tdata )
|
||||
|
||||
assert( ~(( CDRIn(i).io.axis.fire & CDRIn(i).io.axis.bits.tlast) & rxCnt(i) =/= 3.U), "Assert Failed! Rx must 4-byte Align!" )
|
||||
|
||||
CDRIn(i).io.axis.ready := true.B
|
||||
|
||||
rxFifo(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
CDRIn(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
|
||||
rxFifo(i).io.deq.ready := isTLReadRxFifo(i)
|
||||
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
isRxError(i) := false.B
|
||||
} .elsewhen( rxFifo(i).io.enq.valid & ~rxFifo(i).io.enq.ready ){
|
||||
isRxError(i) := true.B
|
||||
printf(s"Warning, RxFifo$i Overflow!\n")
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(2+i) ){
|
||||
rxLeft(i) := 0.U
|
||||
} .elsewhen( rxFifo(i).io.enq.fire & rxFifo(i).io.deq.fire ){
|
||||
rxLeft(i) := rxLeft(i)
|
||||
} .elsewhen( rxFifo(i).io.enq.fire ){
|
||||
rxLeft(i) := rxLeft(i) + 1.U
|
||||
} .elsewhen( rxFifo(i).io.deq.fire ){
|
||||
rxLeft(i) := rxLeft(i) - 1.U
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRImplIsLast{ this:TL2CDRImplBase =>
|
||||
io.isOnline := false.B
|
||||
val isReadIsLast = Wire(Bool())
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRImplUserCRC{ this: TL2CDRImplBase =>
|
||||
val isTLWriteTxFifo: Seq[Bool]
|
||||
val isTLReadRxFifo: Seq[Bool]
|
||||
|
||||
val isTLReadTxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLReadRxCrc = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
|
||||
val txCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
val rxCrc = for( i <- 0 until 2 ) yield { Module(new crc32_32) }
|
||||
|
||||
for( i <- 0 until 2 ) {
|
||||
txCrc(i).io.enq.valid := isTLWriteTxFifo(i)
|
||||
txCrc(i).io.enq.bits := bus.a.bits.data
|
||||
|
||||
rxCrc(i).io.enq.valid := isTLReadRxFifo(i)
|
||||
rxCrc(i).io.enq.bits := rxFifo(i).io.deq.bits
|
||||
|
||||
txCrc(i).reset := reset.asBool | isTLWriteSoftReset(0+i)
|
||||
rxCrc(i).reset := reset.asBool | isTLWriteSoftReset(2+i)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
trait TL2CDRImplLimitTimmer{ this: TL2CDRImplBase =>
|
||||
val intRxStart: Seq[Bool]
|
||||
val isTLWriteSoftReset: Seq[Bool]
|
||||
val isTxFifoRelease: Seq[Bool]
|
||||
|
||||
val isTLWriteLimitTimerAim = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
val isTLWriteLimitTxPair = for( i <- 0 until 2 ) yield { Wire(Bool()) }
|
||||
|
||||
val limitTimerCnt = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
|
||||
val limitTimerAim = for( i <- 0 until 2 ) yield { RegInit(0.U(16.W)) }
|
||||
val isLimitTimerTrigger = for( i <- 0 until 2 ) yield { RegInit(false.B) }
|
||||
val txPairSel = for( i <- 0 until 2 ) yield { RegInit((i.U)(2.W)) }
|
||||
|
||||
for( i <- 0 until 2 ){
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
limitTimerCnt(i) := 0.U
|
||||
} .elsewhen( limitTimerCnt(i) =/= limitTimerAim(i) ){
|
||||
when( isLimitTimerTrigger(i) ){
|
||||
limitTimerCnt(i) := limitTimerCnt(i) + 1.U
|
||||
}
|
||||
}
|
||||
|
||||
when( isTLWriteLimitTimerAim(i) ){
|
||||
limitTimerAim(i) := bus.a.bits.data
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
isLimitTimerTrigger(i) := false.B
|
||||
} .elsewhen( intRxStart(i) ){
|
||||
isLimitTimerTrigger(i) := true.B
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset(0+i) | isTLWriteSoftReset(2+i) ){
|
||||
txPairSel(i) := i.U
|
||||
} .elsewhen( isTLWriteLimitTxPair(i) ){
|
||||
txPairSel(i) := bus.a.bits.data
|
||||
}
|
||||
|
||||
|
||||
isTxFifoRelease(i) := ( 0 until 2).map{ lmt =>
|
||||
((txPairSel(lmt) =/= i.U) | (limitTimerCnt(lmt) === limitTimerAim(lmt)))
|
||||
}.reduce(_&_)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class TL2CDRImpl(outer: TL2CDR)(implicit p: Parameters) extends TL2CDRImplBase(outer)
|
||||
with TL2CDRImplTx with TL2CDRImplRx
|
||||
with TL2CDRImplIsLast
|
||||
with TL2CDRImplUserCRC
|
||||
with TL2CDRImplLimitTimmer
|
||||
{
|
||||
|
||||
isTLWriteSoftReset(0) := bus.a.fire & bus.a.bits.address(7,0) === "h00".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxLen(0) := bus.a.fire & bus.a.bits.address(7,0) === "h04".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxFifo(0) := bus.a.fire & bus.a.bits.address(7,0) === "h08".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadTxCrc(0) := bus.a.fire & bus.a.bits.address(7,0) === "h0c".U & bus.a.bits.opcode === 4.U
|
||||
|
||||
isTLWriteSoftReset(1) := bus.a.fire & bus.a.bits.address(7,0) === "h10".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxLen(1) := bus.a.fire & bus.a.bits.address(7,0) === "h14".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteTxFifo(1) := bus.a.fire & bus.a.bits.address(7,0) === "h18".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadTxCrc(1) := bus.a.fire & bus.a.bits.address(7,0) === "h1c".U & bus.a.bits.opcode === 4.U
|
||||
|
||||
isTLWriteSoftReset(2) := bus.a.fire & bus.a.bits.address(7,0) === "h20".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadRxLen(0) := bus.a.fire & bus.a.bits.address(7,0) === "h24".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxFifo(0) := bus.a.fire & bus.a.bits.address(7,0) === "h28".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxCrc(0) := bus.a.fire & bus.a.bits.address(7,0) === "h2c".U & bus.a.bits.opcode === 4.U
|
||||
isTLWriteLimitTimerAim(0) := bus.a.fire & bus.a.bits.address(7,0) === "h30".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteLimitTxPair(0) := bus.a.fire & bus.a.bits.address(7,0) === "h34".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
|
||||
isTLWriteSoftReset(3) := bus.a.fire & bus.a.bits.address(7,0) === "h40".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLReadRxLen(1) := bus.a.fire & bus.a.bits.address(7,0) === "h44".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxFifo(1) := bus.a.fire & bus.a.bits.address(7,0) === "h48".U & ( bus.a.bits.opcode === 4.U )
|
||||
isTLReadRxCrc(1) := bus.a.fire & bus.a.bits.address(7,0) === "h4c".U & bus.a.bits.opcode === 4.U
|
||||
isTLWriteLimitTimerAim(1) := bus.a.fire & bus.a.bits.address(7,0) === "h50".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
isTLWriteLimitTxPair(1) := bus.a.fire & bus.a.bits.address(7,0) === "h54".U & ( (bus.a.bits.opcode === 0.U) || (bus.a.bits.opcode === 1.U) )
|
||||
|
||||
isTLReadStatus := bus.a.fire & bus.a.bits.address(7,0) === "h58".U & ( bus.a.bits.opcode === 4.U )
|
||||
isReadIsLast := bus.a.fire & bus.a.bits.address(7,0) === "h5c".U & ( bus.a.bits.opcode === 4.U )
|
||||
|
||||
int(0) := intTxEnd(0)
|
||||
int(1) := intTxEnd(1)
|
||||
|
||||
int(2) := intRxError(0)
|
||||
int(3) := intRxError(1)
|
||||
|
||||
int(4) := intRxStart(0)
|
||||
int(5) := intRxStart(1)
|
||||
|
||||
int(6) := intRxEnd(0)
|
||||
int(7) := intRxEnd(1)
|
||||
|
||||
int(8) := intTxFifoDeq(0)
|
||||
int(9) := intTxFifoDeq(1)
|
||||
|
||||
int(10) := intRxFifoEnq(0)
|
||||
int(11) := intRxFifoEnq(1)
|
||||
|
||||
|
||||
|
||||
|
||||
val tlaInfo = Reg(new TLBundleA(edge.bundle))
|
||||
val rdata = Reg(UInt(32.W))
|
||||
val tlAReady = RegInit(true.B)
|
||||
val tlDValid = RegInit(false.B)
|
||||
|
||||
val isRead = tlaInfo.opcode === 4.U
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bus.a.ready :=
|
||||
tlAReady &
|
||||
MuxCase( true.B, Array(
|
||||
( bus.a.bits.address(7,0) === "h08".U ) -> txFifo(0).io.enq.ready,
|
||||
( bus.a.bits.address(7,0) === "h18".U ) -> txFifo(1).io.enq.ready,
|
||||
( bus.a.bits.address(7,0) === "h28".U ) -> rxFifo(0).io.deq.valid,
|
||||
( bus.a.bits.address(7,0) === "h48".U ) -> rxFifo(1).io.deq.valid,
|
||||
))
|
||||
|
||||
|
||||
bus.d.valid := tlDValid
|
||||
|
||||
|
||||
|
||||
|
||||
when( bus.a.fire ) {
|
||||
tlaInfo := bus.a.bits
|
||||
}
|
||||
|
||||
when( bus.a.fire ){
|
||||
tlAReady := false.B
|
||||
tlDValid := true.B
|
||||
} .elsewhen( bus.d.fire ) {
|
||||
tlAReady := true.B
|
||||
tlDValid := false.B
|
||||
}
|
||||
|
||||
when(isRead) {
|
||||
bus.d.bits := edge.AccessAck(tlaInfo, rdata)
|
||||
} .otherwise {
|
||||
bus.d.bits := edge.AccessAck(tlaInfo)
|
||||
}
|
||||
|
||||
|
||||
when( isTLReadStatus ){
|
||||
rdata := Cat( txLeft(1), txLeft(0), rxLeft(1), rxLeft(0), isRxValid(1), isRxValid(0), isRxError(1), isRxError(0), isTxBusy(1), isTxBusy(0), isTxFull(1), isTxFull(0) )
|
||||
} .elsewhen(isTLReadRxLen(0) ){
|
||||
rdata := rxLen(0)
|
||||
} .elsewhen(isTLReadRxLen(1) ){
|
||||
rdata := rxLen(1)
|
||||
} .elsewhen(isTLReadRxFifo(0) ){
|
||||
rdata := rxFifo(0).io.deq.bits
|
||||
} .elsewhen(isTLReadRxFifo(1) ){
|
||||
rdata := rxFifo(1).io.deq.bits
|
||||
} .elsewhen(isReadIsLast){
|
||||
rdata := io.isLast
|
||||
} .elsewhen(isTLReadTxCrc(0)){
|
||||
rdata := txCrc(0).io.crc
|
||||
} .elsewhen(isTLReadTxCrc(1)){
|
||||
rdata := txCrc(1).io.crc
|
||||
} .elsewhen(isTLReadRxCrc(0)){
|
||||
rdata := rxCrc(0).io.crc
|
||||
} .elsewhen(isTLReadRxCrc(1)){
|
||||
rdata := rxCrc(1).io.crc
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,304 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
|
||||
|
||||
class CRC_ERR_Bundle extends Bundle{
|
||||
val crc_err = Bool()
|
||||
val crc_err_count = UInt(8.W)
|
||||
val cdr_err = Bool()
|
||||
}
|
||||
|
||||
class Lvds_Bus_MasterIO extends Bundle{
|
||||
val rst_n = Input(Bool())
|
||||
val reset_calib = Input(Bool())
|
||||
val oser_pclk = Input(Bool())
|
||||
val oser_fclk = Input(Bool())
|
||||
val ides_pclk = Input(Bool())
|
||||
val ides_fclk = Input(Bool())
|
||||
|
||||
val lvds_down_dout = Output(Bool())
|
||||
val lvds_up_din = Input(Bool())
|
||||
|
||||
val frame_info_update_en = Input(Bool())
|
||||
val slave_type_num = Input(UInt(8.W))
|
||||
val slave_data_length = Input(UInt(8.W))
|
||||
|
||||
val slave_link_num_valid = Output(Bool())
|
||||
val slave_link_num = Output(UInt(7.W))
|
||||
|
||||
val tx_start = Input(Bool())
|
||||
val tx_data_in = Input(UInt(8.W))
|
||||
val tx_data_ready = Output(Bool())
|
||||
val downstream_busy = Output(Bool())
|
||||
val rx_data_out = Output(UInt(8.W))
|
||||
val rx_data_valid = Output(Bool())
|
||||
|
||||
val upstream_crc_valid = Output(Bool())
|
||||
val upstream_crc_err = Output(Bool())
|
||||
val upstream_crc_err_count = Output(UInt(8.W))
|
||||
|
||||
val upstream_cdr_err = Output(Bool())
|
||||
|
||||
val closed_loop_err = Output(Bool())
|
||||
val link_err_location = Output(UInt(7.W))
|
||||
|
||||
val test_downstream_tx_en = Output(Bool())
|
||||
val test_downstream_tx_8b_data = Output(UInt(8.W))
|
||||
val test_downstream_tx_10b_data = Output(UInt(10.W))
|
||||
val test_upstream_rx_busy = Output(Bool())
|
||||
val test_upstream_rx_10b_data = Output(UInt(10.W))
|
||||
val test_upstream_rx_8b_data = Output(UInt(8.W))
|
||||
}
|
||||
|
||||
class Lvds_Bus_Master extends BlackBox with HasBlackBoxInline {
|
||||
|
||||
val io: Lvds_Bus_MasterIO = IO(new Lvds_Bus_MasterIO)
|
||||
|
||||
setInline("lvds_Bus_Master.v",
|
||||
"""
|
||||
| module Lvds_Bus_Master(
|
||||
| input rst_n,
|
||||
| input reset_calib,
|
||||
| input oser_pclk,
|
||||
| input oser_fclk,
|
||||
| input ides_pclk,
|
||||
| input ides_fclk,
|
||||
| output lvds_down_dout,
|
||||
| input lvds_up_din,
|
||||
| input frame_info_update_en,
|
||||
| input [7:0] slave_type_num,
|
||||
| input [7:0] slave_data_length,
|
||||
|
|
||||
| output slave_link_num_valid,
|
||||
| output [6:0] slave_link_num,
|
||||
|
|
||||
| input tx_start,
|
||||
| input [7:0] tx_data_in,
|
||||
| output tx_data_ready,
|
||||
| output downstream_busy,
|
||||
| output [7:0] rx_data_out,
|
||||
| output rx_data_valid,
|
||||
| output upstream_crc_valid,
|
||||
| output upstream_crc_err,
|
||||
| output [7:0] upstream_crc_err_count,
|
||||
| output upstream_cdr_err,
|
||||
|
|
||||
| output closed_loop_err,
|
||||
| output [6:0] link_err_location,
|
||||
|
|
||||
| output test_downstream_tx_en,
|
||||
| output [7:0] test_downstream_tx_8b_data,
|
||||
| output [9:0] test_downstream_tx_10b_data,
|
||||
| output test_upstream_rx_busy,
|
||||
| output [9:0] test_upstream_rx_10b_data,
|
||||
| output [7:0] test_upstream_rx_8b_data
|
||||
| );
|
||||
|
|
||||
| lvds_bus_master_top i_lvds_bus_master(
|
||||
| .rst_n(rst_n), //input
|
||||
| .reset_calib(reset_calib), //input
|
||||
| .oser_pclk(oser_pclk), //input
|
||||
| .oser_fclk(oser_fclk), //input
|
||||
| .ides_pclk(ides_pclk), //input
|
||||
| .ides_fclk(ides_fclk), //input
|
||||
|
|
||||
| .lvds_down_dout(lvds_down_dout), //output
|
||||
| .lvds_up_din(lvds_up_din), //input
|
||||
|
|
||||
| .frame_info_update_en(frame_info_update_en), //input
|
||||
| .slave_type_num(slave_type_num), //input [7:0]
|
||||
| .slave_data_length(slave_data_length), //input [7:0]
|
||||
|
|
||||
| .slave_link_num_valid(slave_link_num_valid), //output
|
||||
| .slave_link_num(slave_link_num), //output [6:0]
|
||||
|
|
||||
| .tx_start(tx_start), //input
|
||||
| .tx_data_in(tx_data_in), //input [7:0]
|
||||
| .tx_data_ready(tx_data_ready), //output
|
||||
| .downstream_busy(downstream_busy), //output
|
||||
| .rx_data_out(rx_data_out), //output [7:0]
|
||||
| .rx_data_valid(rx_data_valid), //output
|
||||
| .upstream_crc_valid(upstream_crc_valid), //output
|
||||
| .upstream_crc_err(upstream_crc_err), //output
|
||||
| .upstream_crc_err_count(upstream_crc_err_count), //output [7:0]
|
||||
| .upstream_cdr_err(upstream_cdr_err), //output
|
||||
|
|
||||
| .closed_loop_err(closed_loop_err), //output
|
||||
| .link_err_location(link_err_location), //output [6:0]
|
||||
|
|
||||
| .test_downstream_tx_en(test_downstream_tx_en), //output
|
||||
| .test_downstream_tx_8b_data(test_downstream_tx_8b_data), //output [7:0]
|
||||
| .test_downstream_tx_10b_data(test_downstream_tx_10b_data), //output [9:0]
|
||||
| .test_upstream_rx_busy(test_upstream_rx_busy), //output
|
||||
| .test_upstream_rx_10b_data(test_upstream_rx_10b_data), //output [9:0]
|
||||
| .test_upstream_rx_8b_data(test_upstream_rx_8b_data) //output [7:0]
|
||||
| );
|
||||
|endmodule
|
||||
""".stripMargin)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Lvds_Bus_SlaveIO extends Bundle{
|
||||
val rst_n = Input(Bool())
|
||||
val reset_calib = Input(Bool())
|
||||
val oser_pclk = Input(Bool())
|
||||
val oser_fclk = Input(Bool())
|
||||
val ides_pclk = Input(Bool())
|
||||
val ides_fclk = Input(Bool())
|
||||
|
||||
|
||||
val lvds_down_din = Input(Bool())
|
||||
val lvds_down_dout = Output(Bool())
|
||||
val lvds_up_din = Input(Bool())
|
||||
val lvds_up_dout = Output(Bool())
|
||||
|
||||
val downstream_rx_data_valid = Output(Bool())
|
||||
val downstream_rx_data_out = Output(UInt(8.W))
|
||||
val downstream_rx_crc_valid = Output(Bool())
|
||||
val downstream_rx_crc_err = Output(Bool())
|
||||
val downstream_rx_crc_err_counter = Output(UInt(8.W))
|
||||
val downstream_rx_cdr_err = Output(Bool())
|
||||
val downstream_sync = Output(Bool())
|
||||
|
||||
val upstream_tx_data_ready = Output(Bool())
|
||||
val upstream_tx_data_in = Input(UInt(8.W))
|
||||
|
||||
val upstream_rx_crc_valid = Output(Bool())
|
||||
val upstream_rx_crc_err = Output(Bool())
|
||||
val upstream_rx_crc_err_counter = Output(UInt(8.W))
|
||||
val upstream_rx_cdr_err = Output(Bool())
|
||||
|
||||
val local_slave_id = Output(UInt(7.W))
|
||||
val test_downstream_rx_10b_data = Output(UInt(10.W))
|
||||
val test_downstream_rx_8b_data = Output(UInt(8.W))
|
||||
val test_downstream_rx_state_machine = Output(UInt(4.W))
|
||||
val test_downstream_tx_en = Output(Bool())
|
||||
val test_downstream_tx_8b_data = Output(UInt(8.W))
|
||||
val test_downstream_tx_10b_data = Output(UInt(10.W))
|
||||
val test_upstream_rx_10b_data = Output(UInt(10.W))
|
||||
val test_upstream_rx_8b_data = Output(UInt(8.W))
|
||||
val test_upstream_rx_state_machine = Output(UInt(4.W))
|
||||
val test_upstream_tx_en = Output(Bool())
|
||||
val test_upstream_tx_8b_data = Output(UInt(8.W))
|
||||
val test_upstream_tx_10b_data = Output(UInt(10.W))
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Lvds_Bus_Slave extends BlackBox with HasBlackBoxInline {
|
||||
val io: Lvds_Bus_SlaveIO = IO(new Lvds_Bus_SlaveIO)
|
||||
|
||||
setInline("Lvds_Bus_Slave.v",
|
||||
"""
|
||||
module Lvds_Bus_Slave(
|
||||
| input rst_n,
|
||||
| input reset_calib,
|
||||
| input oser_pclk,
|
||||
| input oser_fclk,
|
||||
| input ides_pclk,
|
||||
| input ides_fclk,
|
||||
|
|
||||
| input lvds_down_din,
|
||||
| output lvds_down_dout,
|
||||
| input lvds_up_din,
|
||||
| output lvds_up_dout,
|
||||
|
|
||||
| output downstream_rx_data_valid,
|
||||
| output downstream_rx_unicast_pkg_valid,
|
||||
| output [7:0] downstream_rx_data_out,
|
||||
| output downstream_rx_crc_valid,
|
||||
| output downstream_rx_crc_err,
|
||||
| output [7:0] downstream_rx_crc_err_counter,
|
||||
| output downstream_rx_cdr_err,
|
||||
| output downstream_sync,
|
||||
| output upstream_tx_data_ready,
|
||||
| output upstream_tx_unicast_pkg_ready,
|
||||
| input [7:0] upstream_tx_data_in,
|
||||
| output upstream_rx_crc_valid,
|
||||
| output upstream_rx_crc_err,
|
||||
| output [7:0] upstream_rx_crc_err_counter,
|
||||
| output upstream_rx_cdr_err,
|
||||
|
|
||||
| output [6:0] local_slave_id,
|
||||
| output [9:0] test_downstream_rx_10b_data,
|
||||
| output [7:0] test_downstream_rx_8b_data,
|
||||
| output [3:0] test_downstream_rx_state_machine,
|
||||
| output test_downstream_tx_en,
|
||||
| output [7:0] test_downstream_tx_8b_data,
|
||||
| output [9:0] test_downstream_tx_10b_data,
|
||||
| output [9:0] test_upstream_rx_10b_data,
|
||||
| output [7:0] test_upstream_rx_8b_data,
|
||||
| output [3:0] test_upstream_rx_state_machine,
|
||||
| output test_upstream_tx_en,
|
||||
| output [7:0] test_upstream_tx_8b_data,
|
||||
| output [9:0] test_upstream_tx_10b_data
|
||||
|);
|
||||
|
|
||||
| lvds_bus_slave_top i_lvds_bus_slave(
|
||||
| .rst_n(rst_n),
|
||||
| .reset_calib(reset_calib),
|
||||
| .oser_pclk(oser_pclk),
|
||||
| .oser_fclk(oser_fclk),
|
||||
| .ides_pclk(ides_pclk),
|
||||
| .ides_fclk(ides_fclk),
|
||||
|
|
||||
| .lvds_down_din(lvds_down_din),
|
||||
| .lvds_down_dout(lvds_down_dout),
|
||||
| .lvds_up_din(lvds_up_din),
|
||||
| .lvds_up_dout(lvds_up_dout),
|
||||
|
|
||||
| .downstream_rx_data_valid(downstream_rx_data_valid),
|
||||
| .downstream_rx_unicast_pkg_valid(downstream_rx_unicast_pkg_valid),
|
||||
| .downstream_rx_data_out(downstream_rx_data_out),
|
||||
| .downstream_rx_crc_valid(downstream_rx_crc_valid),
|
||||
| .downstream_rx_crc_err(downstream_rx_crc_err),
|
||||
| .downstream_rx_crc_err_counter(downstream_rx_crc_err_counter),
|
||||
| .downstream_rx_cdr_err(downstream_rx_cdr_err),
|
||||
| .downstream_sync(downstream_sync),
|
||||
| .upstream_tx_data_ready(upstream_tx_data_ready),
|
||||
| .upstream_tx_unicast_pkg_ready(upstream_tx_unicast_pkg_ready),
|
||||
| .upstream_tx_data_in(upstream_tx_data_in),
|
||||
| .upstream_rx_crc_valid(upstream_rx_crc_valid),
|
||||
| .upstream_rx_crc_err(upstream_rx_crc_err),
|
||||
| .upstream_rx_crc_err_counter(upstream_rx_crc_err_counter),
|
||||
| .upstream_rx_cdr_err(upstream_rx_cdr_err),
|
||||
|
|
||||
| .local_slave_id(local_slave_id), //output[6:0]
|
||||
| .test_downstream_rx_10b_data(test_downstream_rx_10b_data), //output[9:0]
|
||||
| .test_downstream_rx_8b_data(test_downstream_rx_8b_data), //output[7:0]
|
||||
| .test_downstream_rx_state_machine(test_downstream_rx_state_machine), //output[3:0]
|
||||
| .test_downstream_tx_en(test_downstream_tx_en), //output
|
||||
| .test_downstream_tx_8b_data(test_downstream_tx_8b_data), //output[7:0]
|
||||
| .test_downstream_tx_10b_data(test_downstream_tx_10b_data), //output[9:0]
|
||||
| .test_upstream_rx_10b_data(test_upstream_rx_10b_data), //output[9:0]
|
||||
| .test_upstream_rx_8b_data(test_upstream_rx_8b_data), //output[7:0]
|
||||
| .test_upstream_rx_state_machine(test_upstream_rx_state_machine), //output[3:0]
|
||||
| .test_upstream_tx_en(test_upstream_tx_en), //output
|
||||
| .test_upstream_tx_8b_data(test_upstream_tx_8b_data), //output[7:0]
|
||||
| .test_upstream_tx_10b_data(test_upstream_tx_10b_data) //output[9:0]
|
||||
| );
|
||||
|endmodule
|
||||
""".stripMargin)
|
||||
}
|
||||
|
||||
|
||||
//Test Signal//
|
||||
|
||||
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.devices.gpio._
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BackSys()(implicit p: Parameters) extends LazyModule with HasBackParameters {
|
||||
|
||||
|
||||
lazy val module: BackSysImp = new BackSysImp(this)
|
||||
}
|
||||
|
||||
class BackSysImp(outer: BackSys) extends LazyModuleImp(outer) with HasBackParameters {
|
||||
class BackSysIO extends Bundle{
|
||||
val overCLK = Input(Bool())
|
||||
val uDatIn = Input(Bool())
|
||||
val uDatOut = Output(Bool())
|
||||
val dDatIn = Input(Bool())
|
||||
val dDatOut = Output(Bool())
|
||||
|
||||
val out = Output(UInt(32.W))
|
||||
val in = Input(UInt(32.W))
|
||||
|
||||
val isOnline = Output(Bool())
|
||||
val isLast = Input(Bool())
|
||||
val DCIn = Input(Bool())
|
||||
}
|
||||
|
||||
|
||||
val io: BackSysIO = IO(new BackSysIO)
|
||||
|
||||
val pico = Module(new Picorv32_mem )
|
||||
val cdr = Module(new TLCDR() )
|
||||
val gpio = Module(new SimpleGpio() )
|
||||
val sram = Module(new SimpleSRAM)
|
||||
|
||||
|
||||
pico.io.irq := Cat( io.DCIn, cdr.io.interrupt.asUInt )
|
||||
|
||||
|
||||
io.out := gpio.io.out
|
||||
gpio.io.in := io.in
|
||||
|
||||
io.isOnline := gpio.io.isOnline
|
||||
gpio.io.isLast := io.isLast
|
||||
|
||||
|
||||
|
||||
|
||||
cdr.io.overCLK := io.overCLK
|
||||
|
||||
cdr.io.dDatIn := io.dDatIn
|
||||
io.dDatOut := cdr.io.dDatOut
|
||||
cdr.io.uDatIn := io.uDatIn
|
||||
io.uDatOut := cdr.io.uDatOut
|
||||
|
||||
io.out := gpio.io.out
|
||||
|
||||
|
||||
|
||||
|
||||
sram.io.mem.valid := pico.io.mem.valid & pico.io.mem.addr.extract(31) === "b1".U
|
||||
cdr.io.mem.valid := pico.io.mem.valid & pico.io.mem.addr.extract(31) =/= "b1".U & pico.io.mem.addr.extract(10) === "b0".U & ~pico.io.mem.instr
|
||||
gpio.io.mem.valid := pico.io.mem.valid & pico.io.mem.addr.extract(31) =/= "b1".U & pico.io.mem.addr.extract(10) === "b1".U & ~pico.io.mem.instr
|
||||
|
||||
pico.io.mem.ready :=
|
||||
Mux( pico.io.mem.instr | pico.io.mem.addr.extract(31) === "b1".U, sram.io.mem.ready,
|
||||
Mux1H(Seq(
|
||||
( pico.io.mem.addr.extract(10) === "b0".U ) -> cdr.io.mem.ready,
|
||||
( pico.io.mem.addr.extract(10) === "b1".U ) -> gpio.io.mem.ready,
|
||||
))
|
||||
)
|
||||
pico.io.mem.rdata :=
|
||||
Mux( pico.io.mem.instr | pico.io.mem.addr.extract(31) === "b1".U, sram.io.mem.rdata,
|
||||
Mux1H(Seq(
|
||||
( pico.io.mem.addr.extract(10) === "b0".U ) -> cdr.io.mem.rdata,
|
||||
( pico.io.mem.addr.extract(10) === "b1".U ) -> gpio.io.mem.rdata,
|
||||
))
|
||||
)
|
||||
|
||||
sram.io.mem.wdata := pico.io.mem.wdata
|
||||
cdr.io.mem.wdata := pico.io.mem.wdata
|
||||
gpio.io.mem.wdata := pico.io.mem.wdata
|
||||
|
||||
sram.io.mem.wstrb := pico.io.mem.wstrb
|
||||
cdr.io.mem.wstrb := pico.io.mem.wstrb
|
||||
gpio.io.mem.wstrb := pico.io.mem.wstrb
|
||||
|
||||
sram.io.mem.addr := pico.io.mem.addr(11,0)
|
||||
cdr.io.mem.addr := pico.io.mem.addr(11,0)
|
||||
gpio.io.mem.addr := pico.io.mem.addr(11,0)
|
||||
|
||||
sram.io.mem.instr := pico.io.mem.instr
|
||||
cdr.io.mem.instr := false.B
|
||||
gpio.io.mem.instr := false.B
|
||||
|
||||
|
||||
assert( pico.io.mem.wstrb.andR | ~pico.io.mem.wstrb.orR )
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
class Mem_Port_Bundle extends Bundle{
|
||||
val valid = Output(Bool())
|
||||
val ready = Input(Bool())
|
||||
val instr = Output(Bool())
|
||||
|
||||
val addr = Output(UInt(32.W))
|
||||
val wdata = Output(UInt(32.W))
|
||||
val wstrb = Output(UInt(4.W))
|
||||
val rdata = Input(UInt(32.W))
|
||||
|
||||
def fire = valid & ready
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class Picorv32_mem()(implicit p: Parameters) extends BackModule{
|
||||
class Picorv32IO_mem extends Bundle{
|
||||
|
||||
val mem = new Mem_Port_Bundle
|
||||
|
||||
val irq = Input(UInt(32.W))
|
||||
|
||||
}
|
||||
|
||||
val io: Picorv32IO_mem = IO(new Picorv32IO_mem)
|
||||
|
||||
val core = Module(new picorv32)
|
||||
|
||||
core.io.clk := clock.asBool
|
||||
core.io.resetn := ~reset.asBool
|
||||
|
||||
core.io.pcpi_wr := false.B
|
||||
core.io.pcpi_rd := 0.U
|
||||
core.io.pcpi_wait := false.B
|
||||
core.io.pcpi_ready := true.B
|
||||
|
||||
core.io.irq := io.irq
|
||||
|
||||
io.mem.valid := core.io.mem_valid
|
||||
core.io.mem_ready := io.mem.ready
|
||||
|
||||
io.mem.addr := core.io.mem_addr
|
||||
io.mem.wdata := core.io.mem_wdata
|
||||
io.mem.wstrb := core.io.mem_wstrb
|
||||
io.mem.instr := core.io.mem_instr
|
||||
core.io.mem_rdata := io.mem.rdata
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
class Picorv32_tl(edge: TLEdgeOut)(implicit p: Parameters) extends BackModule{
|
||||
class Picorv32IO_tl extends Bundle{
|
||||
val trap = Output(Bool())
|
||||
|
||||
val tla = new DecoupledIO(new TLBundleA(edge.bundle))
|
||||
val tld = Flipped(new DecoupledIO(new TLBundleD(edge.bundle)))
|
||||
|
||||
val irq = Input(UInt(32.W))
|
||||
val eoi = Output(UInt(32.W))
|
||||
}
|
||||
|
||||
val io: Picorv32IO_tl = IO(new Picorv32IO_tl)
|
||||
|
||||
val core = Module(new picorv32)
|
||||
|
||||
core.io.clk := clock.asBool
|
||||
core.io.resetn := ~reset.asBool
|
||||
io.trap := core.io.trap
|
||||
|
||||
core.io.pcpi_wr := false.B
|
||||
core.io.pcpi_rd := 0.U
|
||||
core.io.pcpi_wait := false.B
|
||||
core.io.pcpi_ready := true.B
|
||||
|
||||
core.io.irq := io.irq
|
||||
io.eoi := core.io.eoi
|
||||
|
||||
// val tlStateNext = Wire( UInt(2.W) )
|
||||
// val tlStateCurr = RegNext(tlStateNext, 0.U)
|
||||
|
||||
// tlStateNext := Mux1H(Seq(
|
||||
// (tlStateCurr === 0.U) -> Mux( core.io.mem_valid, 1.U, 0.U ), //IDLE
|
||||
// (tlStateCurr === 1.U) -> Mux( io.tla.fire, 2.U, 1.U ), //A FIRE
|
||||
// (tlStateCurr === 2.U) -> Mux( io.tld.fire, 0.U, 2.U ), //D FIRE
|
||||
// ))
|
||||
|
||||
val isTlaValidAck = RegInit(true.B)
|
||||
|
||||
when( io.tla.fire ){
|
||||
isTlaValidAck := false.B
|
||||
} .elsewhen( io.tld.fire ){
|
||||
isTlaValidAck := true.B
|
||||
}
|
||||
|
||||
core.io.mem_ready := io.tld.fire
|
||||
core.io.mem_rdata := io.tld.bits.data
|
||||
io.tld.ready := true.B
|
||||
io.tla.valid := isTlaValidAck & core.io.mem_valid
|
||||
|
||||
when( core.io.mem_wstrb.orR ){
|
||||
io.tla.bits :=
|
||||
edge.Put(
|
||||
fromSource = 0.U,
|
||||
toAddress = core.io.mem_addr,
|
||||
lgSize = log2Ceil(32/8).U,
|
||||
data = core.io.mem_wdata,
|
||||
mask = core.io.mem_wstrb
|
||||
)._2
|
||||
} .otherwise{
|
||||
io.tla.bits :=
|
||||
edge.Get(
|
||||
fromSource = 0.U,
|
||||
toAddress = core.io.mem_addr,
|
||||
lgSize = log2Ceil(32/8).U
|
||||
)._2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
|
||||
class SimpleGpio()(implicit p: Parameters) extends BackModule{
|
||||
class SimpleGpioIO extends Bundle{
|
||||
val mem = Flipped(new Mem_Port_Bundle)
|
||||
|
||||
val out = Output(UInt(32.W))
|
||||
val in = Input(UInt(32.W))
|
||||
|
||||
|
||||
val isOnline = Output(Bool())
|
||||
val isLast = Input(Bool())
|
||||
|
||||
}
|
||||
|
||||
val io: SimpleGpioIO = IO(new SimpleGpioIO)
|
||||
|
||||
val isWriteGpio = io.mem.fire & io.mem.addr(3,0) === "h0".U & io.mem.wstrb =/= 0.U
|
||||
val isReadGpio = io.mem.fire & io.mem.addr(3,0) === "h0".U & io.mem.wstrb === 0.U
|
||||
// val isWriteDir = io.mem.fire & io.mem.addr(3,0) === "h4".U & io.mem.wstrb =/= 0.U
|
||||
val isReadIsLast = io.mem.fire & io.mem.addr(3,0) === "h8".U & io.mem.wstrb === 0.U
|
||||
|
||||
|
||||
io.isOnline := false.B
|
||||
|
||||
io.out := RegEnable( io.mem.wdata, 0.U(32.W), isWriteGpio )
|
||||
|
||||
io.mem.ready := true.B
|
||||
io.mem.rdata :=
|
||||
Mux( io.mem.addr(3,0) === "h0".U, io.in,
|
||||
Mux( io.mem.addr(3,0) === "h8".U, io.isLast, 0.U ) )
|
||||
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
|
||||
class SimpleSRAM()(implicit p: Parameters) extends BackModule{
|
||||
class SimpleSRAMIO extends Bundle{
|
||||
val mem = Flipped(new Mem_Port_Bundle)
|
||||
}
|
||||
|
||||
val io: SimpleSRAMIO = IO(new SimpleSRAMIO)
|
||||
|
||||
val mem = SyncReadMem(1024, UInt(32.W))
|
||||
|
||||
|
||||
io.mem.rdata := DontCare
|
||||
|
||||
when( io.mem.valid & io.mem.wstrb.extract(0) ){
|
||||
mem.write( io.mem.addr(11,2), io.mem.wdata )
|
||||
|
||||
assert( io.mem.wstrb.extract(1) & io.mem.wstrb.extract(2) & io.mem.wstrb.extract(3) )
|
||||
}
|
||||
|
||||
io.mem.rdata := mem.read(io.mem.addr(11,2), true.B)
|
||||
|
||||
val isReadAck = RegInit(false.B)
|
||||
when( io.mem.fire ){
|
||||
isReadAck := false.B
|
||||
} .elsewhen( io.mem.valid & io.mem.wstrb === 0.U ){
|
||||
isReadAck := true.B
|
||||
}
|
||||
|
||||
io.mem.ready :=
|
||||
( io.mem.wstrb =/= 0.U & true.B ) |
|
||||
( io.mem.wstrb === 0.U & isReadAck )
|
||||
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
|
||||
abstract class TLCDRBase()(implicit p: Parameters) extends BackModule {
|
||||
class TLCDRIO extends Bundle{
|
||||
val overCLK = Input(Bool())
|
||||
val dDatIn = Input(Bool())
|
||||
val dDatOut = Output(Bool())
|
||||
val uDatIn = Input(Bool())
|
||||
val uDatOut = Output(Bool())
|
||||
|
||||
val mem = Flipped(new Mem_Port_Bundle)
|
||||
|
||||
val interrupt = Output(Vec(4, Bool()))
|
||||
}
|
||||
|
||||
val io: TLCDRIO = IO(new TLCDRIO)
|
||||
|
||||
val dirSel = RegInit(false.B)
|
||||
|
||||
val CDRIn = Module(new CDRIn)
|
||||
CDRIn.io.serDat := Mux( ~dirSel, io.dDatIn, io.uDatIn )
|
||||
CDRIn.io.overCLK := io.overCLK
|
||||
|
||||
val CDROut = Module(new CDROut)
|
||||
io.dDatOut := ~dirSel & CDROut.io.serDat
|
||||
io.uDatOut := dirSel & CDROut.io.serDat
|
||||
|
||||
|
||||
|
||||
val txFifo = Module(new Queue(UInt(32.W), 16))
|
||||
val rxFifo = Module(new Queue(UInt(32.W), 16))
|
||||
|
||||
|
||||
val isTLWriteSoftReset = io.mem.fire & io.mem.addr(4,0) === "h10".U & ( (io.mem.wstrb =/= 0.U) )
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait TLCDRTx{ this: TLCDRBase =>
|
||||
|
||||
val isTLReadStatus = io.mem.fire & io.mem.addr(4,0) === "h0".U & ( io.mem.wstrb === 0.U )
|
||||
val isTLWriteTxLen = io.mem.fire & io.mem.addr(4,0) === "h4".U & ( io.mem.wstrb =/= 0.U )
|
||||
val isTLWriteTxFifo = io.mem.fire & io.mem.addr(4,0) === "h8".U & ( io.mem.wstrb =/= 0.U )
|
||||
|
||||
|
||||
val txLen = RegInit(0.U(12.W))
|
||||
val isTxBusy = RegInit(false.B)
|
||||
val isTxFull = ~txFifo.io.enq.ready
|
||||
|
||||
|
||||
val intTxEnd = ShiftRegister( CDROut.io.axis.fire & CDROut.io.axis.bits.tlast, 5, false.B, true.B)
|
||||
println("Warning, TxEnd no confident\n")
|
||||
val intTxFifoFull = ~RegNext(isTxFull, false.B) & isTxFull
|
||||
val intTxFinish = CDROut.io.axis.fire & CDROut.io.axis.bits.tlast
|
||||
|
||||
val txCnt = Reg(UInt(2.W))
|
||||
|
||||
val txData = Reg(UInt(32.W))
|
||||
|
||||
when( txFifo.io.deq.fire ){ //txCnt === 3.U
|
||||
txData := txFifo.io.deq.bits
|
||||
when( isTxBusy ){
|
||||
assert(CDROut.io.axis.fire)
|
||||
}
|
||||
|
||||
} .elsewhen( CDROut.io.axis.fire ){
|
||||
txData := txData << 8
|
||||
}
|
||||
|
||||
txFifo.io.deq.ready :=
|
||||
Mux( isTxBusy, CDROut.io.axis.fire & txCnt === 3.U, true.B )
|
||||
|
||||
txFifo.reset := reset.asBool | isTLWriteTxLen | isTLWriteSoftReset
|
||||
CDROut.reset := reset.asBool | isTLWriteTxLen | isTLWriteSoftReset
|
||||
|
||||
CDROut.io.axis.bits.tdata := txData.head(8)
|
||||
|
||||
// PriorityMux(Seq(
|
||||
// (txCnt === 0.U) -> txData(31, 24),
|
||||
// (txCnt === 1.U) -> txData(23, 16),
|
||||
// (txCnt === 2.U) -> txData(15, 8),
|
||||
// (txCnt === 3.U) -> txData( 7, 0),
|
||||
// ))
|
||||
|
||||
CDROut.io.axis.bits.tlast := ~txFifo.io.deq.valid & txCnt === 3.U
|
||||
CDROut.io.axis.bits.tuser := false.B
|
||||
CDROut.io.axis.valid := isTxBusy
|
||||
|
||||
|
||||
when( isTLWriteTxLen | isTLWriteSoftReset ){
|
||||
isTxBusy := false.B
|
||||
}.elsewhen( txFifo.io.deq.fire & ~isTxBusy ){
|
||||
isTxBusy := true.B
|
||||
} .elsewhen( CDROut.io.axis.fire & CDROut.io.axis.bits.tlast ){
|
||||
isTxBusy := false.B
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteTxLen ){
|
||||
txCnt := 0.U
|
||||
} .elsewhen( CDROut.io.axis.fire ){
|
||||
txCnt := txCnt + 1.U
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteTxLen ){
|
||||
txLen := io.mem.wdata
|
||||
} .elsewhen( CDROut.io.axis.fire ){
|
||||
txLen := txLen - 1.U
|
||||
}
|
||||
|
||||
txFifo.io.enq.bits := io.mem.wdata
|
||||
txFifo.io.enq.valid := isTLWriteTxFifo & txLen =/= 0.U
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
trait TLCDRRx{ this: TLCDRBase =>
|
||||
|
||||
// val isTLReadRxStatus = io.mem.fire & io.mem.addr(4,0) === "h14".U & ( io.mem.wstrb === 0.U )
|
||||
val isTLReadRxLen = io.mem.fire & io.mem.addr(4,0) === "h18".U & ( io.mem.wstrb === 0.U )
|
||||
val isTLReadRxFifo = io.mem.fire & io.mem.addr(4,0) === "h1c".U & ( io.mem.wstrb === 0.U )
|
||||
|
||||
val rxLen = RegInit(0.U(12.W))
|
||||
val isRxValid = rxFifo.io.enq.fire
|
||||
val isRxError = RegInit(false.B)
|
||||
val isAxisEnd = RegInit(false.B)
|
||||
val isRxEnd = isAxisEnd & ~rxFifo.io.deq.valid
|
||||
|
||||
val intRxError = ~RegNext(isRxError, false.B) & isRxError
|
||||
val intRxStart = rxLen === 0.U & CDRIn.io.axis.fire
|
||||
val intRxEnd = ~RegNext(isRxEnd, false.B) & isRxEnd
|
||||
|
||||
|
||||
val rxCnt = RegInit(0.U(2.W))
|
||||
val rxData = Reg(UInt(24.W))
|
||||
|
||||
when(isTLWriteSoftReset ){
|
||||
isAxisEnd := false.B
|
||||
} .elsewhen( CDRIn.io.axis.fire & CDRIn.io.axis.bits.tlast ){
|
||||
isAxisEnd := true.B
|
||||
}
|
||||
|
||||
|
||||
when( isTLWriteSoftReset ){
|
||||
rxCnt := 0.U
|
||||
} .elsewhen( CDRIn.io.axis.fire ){
|
||||
rxCnt := rxCnt + 1.U
|
||||
|
||||
rxData := Cat( rxData, CDRIn.io.axis.bits.tdata )
|
||||
}
|
||||
|
||||
when( isTLWriteSoftReset ){
|
||||
rxLen := 0.U
|
||||
} .elsewhen( CDRIn.io.axis.fire ){
|
||||
rxLen := rxLen + 1.U
|
||||
}
|
||||
|
||||
rxFifo.io.enq.valid := CDRIn.io.axis.fire & rxCnt === 3.U
|
||||
rxFifo.io.enq.bits := Cat( rxData(23, 0) , CDRIn.io.axis.bits.tdata )
|
||||
|
||||
assert( ~(( CDRIn.io.axis.fire & CDRIn.io.axis.bits.tlast) & rxCnt =/= 3.U), "Assert Failed! Rx must 4-byte Align!" )
|
||||
|
||||
CDRIn.io.axis.ready := true.B
|
||||
|
||||
rxFifo.reset := reset.asBool | isTLWriteSoftReset
|
||||
CDRIn.reset := reset.asBool | isTLWriteSoftReset
|
||||
|
||||
rxFifo.io.deq.ready := isTLReadRxFifo
|
||||
|
||||
|
||||
when( isTLWriteSoftReset ){
|
||||
isRxError := false.B
|
||||
} .elsewhen( rxFifo.io.enq.valid & ~rxFifo.io.enq.ready ){
|
||||
isRxError := true.B
|
||||
printf("Warning, RxFifo Overflow!\n")
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
class TLCDR()(implicit p: Parameters) extends TLCDRBase() with TLCDRTx with TLCDRRx{
|
||||
|
||||
val isWriteTransDir = io.mem.fire & io.mem.addr(4,0) === "hc".U & io.mem.wstrb =/= 0.U
|
||||
|
||||
when( isWriteTransDir ){
|
||||
dirSel := io.mem.wdata
|
||||
}
|
||||
|
||||
io.mem.ready :=
|
||||
( io.mem.wstrb =/= 0.U & txFifo.io.enq.ready) |
|
||||
( io.mem.wstrb === 0.U & Mux( io.mem.addr(4,0) === "h1c".U, rxFifo.io.deq.valid, true.B ) )
|
||||
|
||||
io.interrupt(0) := intTxEnd
|
||||
io.interrupt(1) := intRxError
|
||||
io.interrupt(2) := intRxStart
|
||||
io.interrupt(3) := intRxEnd
|
||||
|
||||
|
||||
io.mem.rdata :=
|
||||
Mux1H(Seq(
|
||||
isTLReadStatus -> Cat( isRxValid, isRxError, isTxBusy, isTxFull, false.B),
|
||||
isTLReadRxLen -> rxLen,
|
||||
isTLReadRxFifo -> rxFifo.io.deq.bits
|
||||
))
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package BACK
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental._
|
||||
|
||||
|
||||
|
||||
|
||||
class picorv32 extends BlackBox() with HasBlackBoxResource {
|
||||
val io = IO(new Bundle {
|
||||
val clk = Input(Bool())
|
||||
val resetn = Input(Bool())
|
||||
val trap = Output(Bool())
|
||||
|
||||
val mem_valid = Output(Bool())
|
||||
val mem_instr = Output(Bool())
|
||||
val mem_ready = Input(Bool())
|
||||
|
||||
val mem_addr = Output(UInt(32.W))
|
||||
val mem_wdata = Output(UInt(32.W))
|
||||
val mem_wstrb = Output(UInt(4.W))
|
||||
val mem_rdata = Input(UInt(32.W))
|
||||
|
||||
// Look-Ahead Interface
|
||||
val mem_la_read = Output(Bool())
|
||||
val mem_la_write = Output(Bool())
|
||||
val mem_la_addr = Output(UInt(32.W))
|
||||
val mem_la_wdata = Output(UInt(32.W))
|
||||
val mem_la_wstrb = Output(UInt(4.W))
|
||||
|
||||
// Pico Co-Processor Interface (PCPI)
|
||||
val pcpi_valid = Output(Bool())
|
||||
val pcpi_insn = Output(UInt(32.W))
|
||||
val pcpi_rs1 = Output(UInt(32.W))
|
||||
val pcpi_rs2 = Output(UInt(32.W))
|
||||
val pcpi_wr = Input(Bool())
|
||||
val pcpi_rd = Input(UInt(32.W))
|
||||
val pcpi_wait = Input(Bool())
|
||||
val pcpi_ready = Input(Bool())
|
||||
|
||||
// IRQ Interface
|
||||
val irq = Input(UInt(32.W))
|
||||
val eoi = Output(UInt(32.W))
|
||||
|
||||
// Trace Interface
|
||||
val trace_valid = Output(Bool())
|
||||
val trace_data = Output(UInt(36.W))
|
||||
})
|
||||
addResource("./picorv32.v")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user