2023-06-28 23:43:03 +08:00
package MAC
import chisel3._
import chisel3.util._
2023-07-03 16:25:41 +08:00
import freechips.rocketchip.tilelink._
import freechips.rocketchip.diplomacy._
2023-07-04 15:40:51 +08:00
import org.chipsalliance.cde.config._
2023-07-03 16:25:41 +08:00
2023-06-28 23:43:03 +08:00
2023-07-04 14:26:24 +08:00
2023-06-29 23:28:05 +08:00
2023-06-30 20:21:03 +08:00
2023-07-11 17:45:32 +08:00
abstract class MacTileLinkBase ( edgeIn : TLEdgeIn , edgeOut : TLEdgeOut ) extends Module {
2023-07-04 15:40:51 +08:00
class MacTileLinkSlaveIO extends Bundle {
2023-07-11 17:38:18 +08:00
val A = Flipped ( Decoupled ( new TLBundleA ( edgeIn . bundle ) ) )
val D = Decoupled ( new TLBundleD ( edgeIn . bundle ) )
2023-07-04 15:40:51 +08:00
}
2023-07-07 21:43:06 +08:00
class MacTileLinkMasterIO extends Bundle {
val A = Decoupled ( new TLBundleA ( edgeOut . bundle ) )
val D = Flipped ( Decoupled ( new TLBundleD ( edgeOut . bundle ) ) )
}
2023-07-03 16:25:41 +08:00
2023-07-11 17:45:32 +08:00
class MacTileLinkIO extends Bundle {
2023-07-03 16:25:41 +08:00
2023-07-11 17:38:18 +08:00
val tlSlv = new MacTileLinkSlaveIO
val tlMst = new MacTileLinkMasterIO
2023-07-03 16:25:41 +08:00
// Tx Status signals
val RetryCntLatched = Input ( UInt ( 4. W ) ) // Latched Retry Counter
val RetryLimit = Input ( Bool ( ) ) // Retry limit reached (Retry Max value +1 attempts were made)
val LateCollLatched = Input ( Bool ( ) ) // Late collision occured
val DeferLatched = Input ( Bool ( ) ) // Defer indication (Frame was defered before sucessfully sent)
val CarrierSenseLost = Input ( Bool ( ) ) // Carrier Sense was lost during the frame transmission
// Tx
val PerPacketCrcEn = Output ( Bool ( ) ) // Per packet crc enable
val PerPacketPad = Output ( Bool ( ) ) // Per packet pading
2023-07-20 10:35:56 +08:00
//Register
val r_TxEn = Input ( Bool ( ) ) // Transmit enable
// Interrupts
val TxB_IRQ = Output ( Bool ( ) )
val TxE_IRQ = Output ( Bool ( ) )
2023-10-12 15:42:49 +08:00
2023-10-08 11:34:36 +08:00
val BlockingTxStatusWrite = Output ( Bool ( ) )
2023-10-13 15:21:53 +08:00
val TxUsedData = Input ( Bool ( ) ) // Transmit packet used data
2023-10-12 18:37:12 +08:00
2023-10-08 11:34:36 +08:00
val TxValidBytesLatched = Output ( UInt ( 2. W ) )
2023-10-10 16:48:32 +08:00
2023-10-08 11:34:36 +08:00
val TxRetrySync = Input ( Bool ( ) )
val TxAbortSync = Input ( Bool ( ) ) // Transmit packet abort
val TxDoneSync = Input ( Bool ( ) ) // Transmission ended
2023-10-08 15:13:35 +08:00
2023-10-12 15:42:49 +08:00
2023-10-12 18:37:12 +08:00
val r_RxEn = Input ( Bool ( ) ) // Receive enable
2023-10-08 15:13:35 +08:00
val RxDataLatched2_rxclk = Input ( UInt ( 32. W ) )
val WriteRxDataToFifoSync = Input ( Bool ( ) )
val RxAbortSync = Input ( Bool ( ) )
val LatchedRxLength_rxclk = Input ( UInt ( 16. W ) )
val RxStatusInLatched_rxclk = Input ( UInt ( 9. W ) )
val ShiftEndedSync = Input ( Bool ( ) )
val RxReady = Output ( Bool ( ) )
2023-10-12 15:42:49 +08:00
val rxDeq = new RevBuff_Enq_Bundle
2023-10-11 18:48:05 +08:00
2023-10-13 15:21:53 +08:00
val TxStartFrm_wb = Output ( Bool ( ) )
val TxStartFrm_syncb = Input ( Bool ( ) )
val TxEndFrm_wb = Output ( Bool ( ) )
val TxData_wb = Output ( UInt ( 32. W ) )
val ReadTxDataFromFifo_sync = Input ( Bool ( ) )
2023-06-28 23:43:03 +08:00
2023-10-12 18:37:12 +08:00
val txEnq = Flipped ( new TxBuff_Deq_Bundle )
2023-06-28 23:43:03 +08:00
2023-06-30 16:00:02 +08:00
2023-10-12 18:37:12 +08:00
}
2023-06-28 23:43:03 +08:00
2023-10-12 18:37:12 +08:00
val io = IO ( new MacTileLinkIO )
2023-06-30 16:00:02 +08:00
2023-10-08 18:27:49 +08:00
val ShiftEndedSyncPluse = io . ShiftEndedSync & ~ RegNext ( io . ShiftEndedSync , false . B )
val RxAbortPluse = io . RxAbortSync & ~ RegNext ( io . RxAbortSync , false . B )
val WriteRxDataToFifoSyncPluse = io . WriteRxDataToFifoSync & ~ RegNext ( io . WriteRxDataToFifoSync , false . B )
2023-06-28 23:43:03 +08:00
2023-10-11 18:48:05 +08:00
val RxReady = RegInit ( false . B ) ; io . RxReady : = RxReady
2023-06-29 18:29:54 +08:00
2023-06-28 23:43:03 +08:00
2023-10-12 15:42:49 +08:00
val rxDeqCtrlValid = RegInit ( false . B )
io . rxDeq . ctrl . valid : = rxDeqCtrlValid
io . rxDeq . ctrl . bits . LatchedRxLength : = RegEnable ( io . LatchedRxLength_rxclk , ShiftEndedSyncPluse | RxAbortPluse )
io . rxDeq . ctrl . bits . RxStatusInLatched : = RegEnable ( io . RxStatusInLatched_rxclk , ShiftEndedSyncPluse | RxAbortPluse )
io . rxDeq . ctrl . bits . isRxAbort : = RegEnable ( RxAbortPluse , false . B , ShiftEndedSyncPluse | RxAbortPluse )
2023-06-28 23:43:03 +08:00
2023-10-12 15:42:49 +08:00
when ( io . rxDeq . ctrl . fire ) {
rxDeqCtrlValid : = false . B
} . elsewhen ( ShiftEndedSyncPluse | RxAbortPluse ) {
rxDeqCtrlValid : = true . B
}
2023-06-28 23:43:03 +08:00
2023-10-11 18:48:05 +08:00
// RxReady generation
2023-10-12 15:42:49 +08:00
when ( ShiftEndedSyncPluse | RxAbortPluse ) {
2023-10-11 18:48:05 +08:00
RxReady : = false . B
2023-10-12 15:42:49 +08:00
} . elsewhen ( io . r_RxEn & ( io . rxDeq . data . ready ) ) {
2023-10-11 18:48:05 +08:00
RxReady : = true . B
}
2023-06-28 23:43:03 +08:00
2023-10-12 15:42:49 +08:00
io . rxDeq . data . bits : = io . RxDataLatched2_rxclk
io . rxDeq . data . valid : = WriteRxDataToFifoSyncPluse
2023-06-28 23:43:03 +08:00
2023-10-12 15:42:49 +08:00
assert ( ( ~ io . rxDeq . data . valid & ~ io . rxDeq . data . ready ) , "Assert Failed, rx overrun!" )
2023-06-28 23:43:03 +08:00
2023-09-26 21:41:19 +08:00
2023-06-28 23:43:03 +08:00
2023-10-08 18:27:49 +08:00
2023-10-11 18:48:05 +08:00
2023-10-12 18:37:12 +08:00
val TxStartFrm_wb = RegInit ( false . B ) ; io . TxStartFrm_wb : = TxStartFrm_wb
2023-10-11 18:48:05 +08:00
2023-10-12 18:37:12 +08:00
when ( io . txEnq . ctrl . fire ) {
TxStartFrm_wb : = true . B
} . elsewhen ( io . TxStartFrm_syncb ) {
TxStartFrm_wb : = false . B
}
2023-10-11 18:48:05 +08:00
2023-10-13 15:21:53 +08:00
when ( ( TxLength === 0. U ) & io . TxUsedData ) {
TxEndFrm_wb : = true . B
} . elsewhen ( TxRetryPulse | TxDonePulse | TxAbortPulse ) {
TxEndFrm_wb : = false . B
}
when ( io . txEnq . ctrl . fire ) {
TxStatus : = Cat ( txBuffDesc . irq , txBuffDesc . wr , txBuffDesc . pad , txBuffDesc . crc ) // Latching status from the tx buffer descriptor Data is avaliable one cycle after the access is started (at that time signal TxEn is not active)
TxLength : = io . txEnq . ctrl . bits . txLength //Latching length from the buffer descriptor;
LatchedTxLength : = io . txEnq . ctrl . bits . txLength
} . elsewhen ( io . txEnq . data . fire ) {
when ( TxLength < 4. U ) {
TxLength : = 0. U
} . otherwise {
TxLength : = TxLength - 4. U // Length is subtracted at the data request
}
}
tx_fifo . io . data_in : = io . tlMst . D . bits . data
tx_fifo . io . write : = io . tlMst . D . fire & io . tlMst . D . bits . opcode === 1. U
io . txEnq . data . ready : = ReadTxDataFromFifoSyncPluse & ~ tx_fifo . io . empty
assert ( ~ ( io . txEnq . data . ready & ~ io . txEnq . data . valid ) , "Assert Failed, Tx should never under run!" )
io . TxData_wb : = io . txEnq . data . bits
tx_fifo . io . clear : = TxAbortPacket | TxRetryPacket
2023-10-11 18:48:05 +08:00
2023-10-12 15:42:49 +08:00
val TxRetryPacket = RegInit ( false . B )
val TxRetryPacket_NotCleared = RegInit ( false . B )
2023-10-12 18:37:12 +08:00
2023-10-12 15:42:49 +08:00
val TxDonePacket = RegInit ( false . B )
val TxDonePacket_NotCleared = RegInit ( false . B )
2023-10-12 18:37:12 +08:00
2023-10-12 15:42:49 +08:00
val TxAbortPacket = RegInit ( false . B )
val TxAbortPacket_NotCleared = RegInit ( false . B )
2023-10-12 18:37:12 +08:00
2023-10-12 15:42:49 +08:00
val TxBDReady = RegInit ( false . B )
val TxBDAddress = RegInit ( 0. U ( 7. W ) ) //[7:1]
2023-10-11 18:48:05 +08:00
2023-10-12 15:42:49 +08:00
val ReadTxDataFromFifoSyncPluse = io . ReadTxDataFromFifo_sync & ~ RegNext ( io . ReadTxDataFromFifo_sync , false . B )
2023-10-11 18:48:05 +08:00
val ( _ , _ , isLastD , transDCnt ) = edgeOut . count ( io . tlMst . D )
val tx_fifo = Module ( new MacFifo ( dw = 32 , dp = 16 ) )
val TxB_IRQ = RegInit ( false . B ) ; io . TxB_IRQ : = TxB_IRQ
val TxE_IRQ = RegInit ( false . B ) ; io . TxE_IRQ : = TxE_IRQ
val TxBDRead = RegInit ( true . B )
val TxStatusWrite = Wire ( Bool ( ) )
val TxLength = RegInit ( 0. U ( 16. W ) )
val TxStatus = RegInit ( 0. U ( 4. W ) ) //[14:11]
2023-10-12 18:37:12 +08:00
2023-10-11 18:48:05 +08:00
val TxRetryPulse = io . TxRetrySync & ~ RegNext ( io . TxRetrySync , false . B )
val TxDonePulse = io . TxDoneSync & ~ RegNext ( io . TxDoneSync , false . B )
val TxAbortPulse = io . TxAbortSync & ~ RegNext ( io . TxAbortSync , false . B )
val LatchedTxLength = RegInit ( 0. U ( 16. W ) )
val BlockingTxStatusWrite = RegInit ( false . B ) ; io . BlockingTxStatusWrite : = BlockingTxStatusWrite
val BlockingTxBDRead = RegInit ( false . B )
val BDWrite = RegInit ( 0. U ( 4. W ) ) // BD Write Enable for access from WISHBONE side
val BDRead = RegInit ( false . B ) // BD Read access from WISHBONE side
val TxEndFrm_wb = RegInit ( false . B ) ; io . TxEndFrm_wb : = TxEndFrm_wb
2023-06-28 23:43:03 +08:00
// Delayed stage signals
2023-07-20 10:35:56 +08:00
val r_TxEn_q = RegNext ( io . r_TxEn , false . B )
2023-06-28 23:43:03 +08:00
2023-09-26 21:41:19 +08:00
def StateIdle = 0. U ( 3. W )
def StateWB = 1. U ( 3. W )
def StateTX = 2. U ( 3. W )
val stateNxt = RegInit ( StateWB )
val stateCur = RegNext ( stateNxt , StateIdle )
2023-06-28 23:43:03 +08:00
val ram_addr = RegInit ( 0. U ( 8. W ) )
val ram_di = RegInit ( 0. U ( 32. W ) )
2023-10-08 18:27:49 +08:00
2023-06-28 23:43:03 +08:00
2023-06-30 14:46:23 +08:00
2023-06-28 23:43:03 +08:00
val TxPointerRead = RegInit ( false . B )
val TxEn_needed = RegInit ( false . B )
2023-10-11 18:48:05 +08:00
2023-06-28 23:43:03 +08:00
2023-10-08 15:13:35 +08:00
2023-06-29 18:29:54 +08:00
val BlockReadTxDataFromMemory = RegInit ( false . B )
2023-06-28 23:43:03 +08:00
2023-06-29 18:29:54 +08:00
val ReadTxDataFromMemory = RegInit ( false . B )
2023-06-28 23:43:03 +08:00
2023-06-29 18:29:54 +08:00
val MasterWbTX = RegInit ( false . B )
2023-06-28 23:43:03 +08:00
2023-06-29 18:29:54 +08:00
val TxPointerMSB = RegInit ( 0. U ( 30. W ) ) //[31:2]
2023-06-28 23:43:03 +08:00
2023-07-07 21:43:06 +08:00
2023-06-28 23:43:03 +08:00
// Generic synchronous single-port RAM interface
2023-06-29 18:29:54 +08:00
val bd_ram = Module ( new MacSRAM )
2023-10-08 18:27:49 +08:00
val txBuffDesc = bd_ram . io . dato . asTypeOf ( new TxBuffDesc )
2023-06-28 23:43:03 +08:00
2023-10-08 18:27:49 +08:00
bd_ram . io . we : =
Mux1H ( Seq (
( stateNxt === StateWB & stateCur === StateWB ) -> BDWrite ,
2023-10-11 18:48:05 +08:00
( TxStatusWrite ) -> "b1111" . U
2023-10-08 18:27:49 +08:00
) ) . asBools
2023-06-28 23:43:03 +08:00
2023-10-08 18:27:49 +08:00
bd_ram . io . oe : =
Mux1H ( Seq (
( ( stateNxt === StateWB ) & ( stateCur === StateWB ) ) -> BDRead ,
( ( stateNxt === StateTX ) & ( stateCur === StateTX ) ) -> ( TxBDRead | TxPointerRead ) ,
) )
2023-06-28 23:43:03 +08:00
2023-06-29 18:29:54 +08:00
bd_ram . io . addr : = ram_addr
bd_ram . io . di : = ram_di
2023-06-28 23:43:03 +08:00
2023-09-26 21:41:19 +08:00
when ( ~ TxBDReady & io . r_TxEn & stateNxt === StateWB & stateCur =/= StateWB ) {
2023-06-28 23:43:03 +08:00
TxEn_needed : = true . B
2023-09-26 21:41:19 +08:00
} . elsewhen ( TxPointerRead & stateNxt === StateTX & stateCur === StateTX ) {
2023-06-28 23:43:03 +08:00
TxEn_needed : = false . B
}
// Enabling access to the RAM for three devices.
2023-06-29 18:29:54 +08:00
// Switching between three stages depends on enable signals
2023-09-26 21:41:19 +08:00
switch ( stateCur ) {
is ( StateIdle ) {
2023-10-11 18:48:05 +08:00
when ( TxEn_needed === false . B ) {
2023-09-26 21:41:19 +08:00
stateNxt : = StateWB // Idle state. We go to WbEn access stage.
ram_addr : = io . tlSlv . A . bits . address ( 9 , 2 ) // [11:2 ] -> [9:2]
ram_di : = io . tlSlv . A . bits . data
2023-10-08 18:27:49 +08:00
BDWrite : = io . tlSlv . A . bits . mask & Fill ( 4 , io . tlSlv . A . valid & io . tlSlv . A . bits . address ( 10 ) & ( ( io . tlSlv . A . bits . opcode === 0. U ) || ( io . tlSlv . A . bits . opcode === 1. U ) ) )
BDRead : = io . tlSlv . A . bits . mask . orR & io . tlSlv . A . valid & io . tlSlv . A . bits . address ( 10 ) & ( io . tlSlv . A . bits . opcode === 4. U ) // 0x400 - 0x7FF
2023-09-26 21:41:19 +08:00
}
}
is ( StateWB ) {
2023-10-11 18:48:05 +08:00
when ( TxEn_needed ) {
2023-09-26 21:41:19 +08:00
stateNxt : = StateTX // wb access stage, r_RxEn is disabled but r_TxEn is enabled
ram_addr : = Cat ( TxBDAddress , TxPointerRead ) //[7,1] + [0]
2023-10-13 15:21:53 +08:00
ram_di : = Cat ( LatchedTxLength , 0. U ( 1. W ) , TxStatus , 0. U ( 2. W ) , false . B , io . RetryCntLatched , io . RetryLimit , io . LateCollLatched , io . DeferLatched , io . CarrierSenseLost )
2023-09-26 21:41:19 +08:00
} . otherwise {
stateNxt : = StateIdle // WbEn access stage and there is no need for other stages. WbEn needs to be switched off for a bit
}
}
is ( StateTX ) {
when ( true . B ) {
stateNxt : = StateWB // TxEn access stage (we always go to wb access stage)
ram_addr : = io . tlSlv . A . bits . address ( 9 , 2 ) //[11:2 ] ->[9:2]
ram_di : = io . tlSlv . A . bits . data
2023-10-08 18:27:49 +08:00
BDWrite : = io . tlSlv . A . bits . mask & Fill ( 4 , io . tlSlv . A . valid & io . tlSlv . A . bits . address ( 10 ) & ( ( io . tlSlv . A . bits . opcode === 0. U ) || ( io . tlSlv . A . bits . opcode === 1. U ) ) )
BDRead : = io . tlSlv . A . bits . mask . orR & io . tlSlv . A . valid & io . tlSlv . A . bits . address ( 10 ) & ( io . tlSlv . A . bits . opcode === 4. U )
2023-09-26 21:41:19 +08:00
}
}
2023-06-29 18:29:54 +08:00
}
2023-09-26 21:41:19 +08:00
2023-06-30 16:00:02 +08:00
val ResetTxBDReady = TxDonePulse | TxAbortPulse | TxRetryPulse
2023-06-28 23:43:03 +08:00
2023-06-29 18:29:54 +08:00
2023-06-28 23:43:03 +08:00
// Latching READY status of the Tx buffer descriptor
2023-09-26 21:41:19 +08:00
when ( stateNxt === StateTX & stateCur === StateTX & TxBDRead ) { // TxBDReady is sampled only once at the beginning.
2023-06-29 23:28:05 +08:00
TxBDReady : = txBuffDesc . rd & ( txBuffDesc . len > 4. U )
2023-06-28 23:43:03 +08:00
} . elsewhen ( ResetTxBDReady ) { // Only packets larger then 4 bytes are transmitted.
TxBDReady : = false . B
}
2023-06-30 14:46:23 +08:00
val StartTxBDRead = ( TxRetryPacket_NotCleared | TxStatusWrite ) & ~ BlockingTxBDRead & ~ TxBDReady // Reading the Tx buffer descriptor
2023-06-28 23:43:03 +08:00
when ( StartTxBDRead ) {
TxBDRead : = true . B
} . elsewhen ( TxBDReady ) {
TxBDRead : = false . B
}
// Reading Tx BD Pointer
2023-10-08 18:27:49 +08:00
when ( TxBDRead & TxBDReady ) {
2023-06-28 23:43:03 +08:00
TxPointerRead : = true . B
2023-09-26 21:41:19 +08:00
} . elsewhen ( stateCur === StateTX ) {
2023-06-28 23:43:03 +08:00
TxPointerRead : = false . B
}
// Writing status back to the Tx buffer descriptor
2023-09-26 21:41:19 +08:00
TxStatusWrite : = ( TxDonePacket_NotCleared | TxAbortPacket_NotCleared ) & stateNxt === StateTX & stateCur === StateTX & ~ BlockingTxStatusWrite
2023-06-28 23:43:03 +08:00
2023-06-30 16:00:02 +08:00
// Status writing must occur only once. Meanwhile it is blocked.
2023-10-08 11:34:36 +08:00
when ( ~ io . TxDoneSync & ~ io . TxAbortSync ) {
2023-06-28 23:43:03 +08:00
BlockingTxStatusWrite : = false . B
} . elsewhen ( TxStatusWrite ) {
BlockingTxStatusWrite : = true . B
}
2023-09-28 18:45:14 +08:00
2023-06-28 23:43:03 +08:00
// TxBDRead state is activated only once.
when ( StartTxBDRead ) {
BlockingTxBDRead : = true . B
} . elsewhen ( ~ StartTxBDRead & ~ TxBDReady ) {
BlockingTxBDRead : = false . B
}
2023-10-08 18:27:49 +08:00
2023-06-28 23:43:03 +08:00
2023-10-08 18:27:49 +08:00
2023-10-13 15:21:53 +08:00
2023-06-28 23:43:03 +08:00
2023-07-07 21:43:06 +08:00
2023-06-28 23:43:03 +08:00
2023-09-26 21:41:19 +08:00
when ( stateNxt === StateTX & stateCur === StateTX & TxPointerRead ) {
2023-10-08 18:27:49 +08:00
TxPointerMSB : = bd_ram . io . dato ( 31 , 2 ) // Latching Tx buffer pointer from buffer descriptor. Only 30 MSB bits are latched because TxPointerMSB is only used for word-aligned accesses.
when ( bd_ram . io . dato ( 1 , 0 ) =/= 0. U ) {
2023-09-27 16:31:56 +08:00
printf ( "Warning, force to align at tx ram" )
}
2023-07-11 17:38:18 +08:00
} . elsewhen ( io . tlMst . D . fire & io . tlMst . D . bits . opcode === 1. U ) {
2023-06-28 23:43:03 +08:00
TxPointerMSB : = TxPointerMSB + 1. U // TxPointer is word-aligned
}
2023-06-29 18:29:54 +08:00
2023-06-28 23:43:03 +08:00
2023-07-07 21:43:06 +08:00
val isTlMstBusy = RegInit ( false . B )
2023-06-28 23:43:03 +08:00
2023-06-30 14:46:23 +08:00
when ( ( TxLength === 0. U ) | TxAbortPulse | TxRetryPulse ) {
2023-06-28 23:43:03 +08:00
ReadTxDataFromMemory : = false . B
2023-09-26 21:41:19 +08:00
} . elsewhen ( stateNxt === StateTX & stateCur === StateTX & TxPointerRead ) {
2023-06-28 23:43:03 +08:00
ReadTxDataFromMemory : = true . B
}
2023-07-07 21:43:06 +08:00
val ReadTxDataFromMemory_2 = ReadTxDataFromMemory & ~ BlockReadTxDataFromMemory ;
2023-06-28 23:43:03 +08:00
2023-07-07 21:43:06 +08:00
when (
2023-10-08 18:27:49 +08:00
( tx_fifo . io . almost_full | TxLength <= 4. U ) & MasterWbTX & isTlMstBusy & ( ~ ( TxAbortPacket_NotCleared | TxRetryPacket_NotCleared ) ) ) {
2023-06-28 23:43:03 +08:00
BlockReadTxDataFromMemory : = true . B
2023-10-08 18:27:49 +08:00
} . elsewhen ( ReadTxDataFromFifoSyncPluse | TxDonePacket | TxAbortPacket | TxRetryPacket ) {
2023-06-28 23:43:03 +08:00
BlockReadTxDataFromMemory : = false . B
}
2023-10-13 15:21:53 +08:00
val TxError = io . RetryLimit | io . LateCollLatched | io . CarrierSenseLost
2023-10-11 18:48:05 +08:00
// Tx Done Interrupt
when ( TxStatusWrite & TxIRQEn ) {
TxB_IRQ : = ~ TxError
} . otherwise {
TxB_IRQ : = false . B
}
// Tx Error Interrupt
when ( TxStatusWrite & TxIRQEn ) {
TxE_IRQ : = TxError
} . otherwise {
TxE_IRQ : = false . B
}
2023-06-28 23:43:03 +08:00
2023-07-07 21:43:06 +08:00
2023-06-28 23:43:03 +08:00
2023-07-07 21:43:06 +08:00
2023-10-08 18:27:49 +08:00
2023-06-28 23:43:03 +08:00
// Marks which bytes are valid within the word.
2023-10-08 11:34:36 +08:00
val TxValidBytesLatched = RegInit ( 0. U ( 2. W ) ) ; io . TxValidBytesLatched : = TxValidBytesLatched
2023-09-26 21:41:19 +08:00
2023-06-28 23:43:03 +08:00
2023-10-08 18:27:49 +08:00
val LatchValidBytes = ShiftRegisters ( ( TxLength < 4. U ) & TxBDReady , 2 , false . B , true . B )
val LatchValidBytesPluse = LatchValidBytes ( 0 ) & ~ LatchValidBytes ( 1 )
2023-06-28 23:43:03 +08:00
// Latching valid bytes
2023-10-08 18:27:49 +08:00
when ( LatchValidBytesPluse ) {
TxValidBytesLatched : = Mux ( TxLength < 4. U , TxLength ( 1 , 0 ) , 0. U )
2023-06-28 23:43:03 +08:00
} . elsewhen ( TxRetryPulse | TxDonePulse | TxAbortPulse ) {
TxValidBytesLatched : = 0. U
}
2023-06-30 16:00:02 +08:00
val TxIRQEn = TxStatus . extract ( 3 ) //[14:11]
val WrapTxStatusBit = TxStatus . extract ( 2 )
2023-06-29 18:29:54 +08:00
io . PerPacketPad : = TxStatus . extract ( 1 )
io . PerPacketCrcEn : = TxStatus . extract ( 0 )
2023-06-28 23:43:03 +08:00
2023-10-11 18:48:05 +08:00
2023-06-28 23:43:03 +08:00
// Latching Tx buffer descriptor address
2023-07-20 10:35:56 +08:00
when ( io . r_TxEn & ( ~ r_TxEn_q ) ) {
2023-06-28 23:43:03 +08:00
TxBDAddress : = 0. U
} . elsewhen ( TxStatusWrite ) {
2023-10-08 18:27:49 +08:00
when ( TxStatusWrite & ~ WrapTxStatusBit ) { //increase
TxBDAddress : = TxBDAddress + 1. U
} . otherwise { //wrap
TxBDAddress : = 0. U
}
2023-06-28 23:43:03 +08:00
}
2023-09-26 21:41:19 +08:00
2023-06-29 18:29:54 +08:00
2023-06-28 23:43:03 +08:00
val TxAbortPacketBlocked = RegInit ( false . B )
2023-06-30 16:00:02 +08:00
when (
2023-10-08 11:34:36 +08:00
io . TxAbortSync & ( ~ TxAbortPacketBlocked ) & MasterWbTX & io . tlMst . D . fire & isLastD |
io . TxAbortSync & ( ~ TxAbortPacketBlocked ) & ( ~ MasterWbTX ) ) {
2023-06-28 23:43:03 +08:00
TxAbortPacket : = true . B
} . otherwise {
TxAbortPacket : = false . B
}
2023-09-26 21:41:19 +08:00
when ( stateNxt === StateTX & stateCur === StateTX & TxAbortPacket_NotCleared ) {
2023-06-28 23:43:03 +08:00
TxAbortPacket_NotCleared : = false . B
2023-06-30 16:00:02 +08:00
} . elsewhen (
2023-10-08 11:34:36 +08:00
io . TxAbortSync & ( ~ TxAbortPacketBlocked ) & MasterWbTX & io . tlMst . D . fire & isLastD |
io . TxAbortSync & ( ~ TxAbortPacketBlocked ) & ( ~ MasterWbTX ) ) {
2023-06-28 23:43:03 +08:00
TxAbortPacket_NotCleared : = true . B
}
2023-10-08 11:34:36 +08:00
when ( ~ io . TxAbortSync & RegNext ( io . TxAbortSync , false . B ) ) {
2023-06-28 23:43:03 +08:00
TxAbortPacketBlocked : = false . B
} . elsewhen ( TxAbortPacket ) {
TxAbortPacketBlocked : = true . B
}
val TxRetryPacketBlocked = RegInit ( false . B )
when (
2023-10-08 11:34:36 +08:00
io . TxRetrySync & ~ TxRetryPacketBlocked & MasterWbTX & io . tlMst . D . fire & isLastD |
io . TxRetrySync & ~ TxRetryPacketBlocked & ~ MasterWbTX ) {
2023-06-28 23:43:03 +08:00
TxRetryPacket : = true . B
} . otherwise {
TxRetryPacket : = false . B
}
when ( StartTxBDRead ) {
TxRetryPacket_NotCleared : = false . B
} . elsewhen (
2023-10-08 11:34:36 +08:00
io . TxRetrySync & ~ TxRetryPacketBlocked & MasterWbTX & io . tlMst . D . fire & isLastD |
io . TxRetrySync & ~ TxRetryPacketBlocked & ~ MasterWbTX ) {
2023-06-28 23:43:03 +08:00
TxRetryPacket_NotCleared : = true . B
}
2023-10-08 11:34:36 +08:00
when ( ~ io . TxRetrySync & RegNext ( io . TxRetrySync , false . B ) ) {
2023-06-28 23:43:03 +08:00
TxRetryPacketBlocked : = false . B
} . elsewhen ( TxRetryPacket ) {
TxRetryPacketBlocked : = true . B
}
val TxDonePacketBlocked = RegInit ( false . B )
when (
2023-10-08 11:34:36 +08:00
io . TxDoneSync & ~ TxDonePacketBlocked & MasterWbTX & io . tlMst . D . fire & isLastD |
io . TxDoneSync & ~ TxDonePacketBlocked & ~ MasterWbTX ) {
2023-06-28 23:43:03 +08:00
TxDonePacket : = true . B
} . otherwise {
TxDonePacket : = false . B
}
2023-09-26 21:41:19 +08:00
when ( stateNxt === StateTX & stateCur === StateTX & TxDonePacket_NotCleared ) {
2023-06-28 23:43:03 +08:00
TxDonePacket_NotCleared : = false . B
} . elsewhen (
2023-10-08 11:34:36 +08:00
io . TxDoneSync & ~ TxDonePacketBlocked & MasterWbTX & io . tlMst . D . fire & isLastD |
io . TxDoneSync & ~ TxDonePacketBlocked & ~ MasterWbTX ) {
2023-06-28 23:43:03 +08:00
TxDonePacket_NotCleared : = true . B
}
2023-10-08 11:34:36 +08:00
when ( ~ io . TxDoneSync & RegNext ( io . TxDoneSync , false . B ) ) {
2023-06-28 23:43:03 +08:00
TxDonePacketBlocked : = false . B
} . elsewhen ( TxDonePacket ) {
TxDonePacketBlocked : = true . B
}
2023-06-29 18:29:54 +08:00
2023-06-28 23:43:03 +08:00
2023-10-13 15:21:53 +08:00
2023-06-28 23:43:03 +08:00
2023-10-08 18:27:49 +08:00
2023-06-28 23:43:03 +08:00
2023-10-08 18:27:49 +08:00
2023-06-29 18:29:54 +08:00
2023-10-08 18:27:49 +08:00
val slvAInfo = RegEnable ( io . tlSlv . A . bits , io . tlSlv . A . fire )
val slvDValid = RegInit ( false . B ) ; io . tlSlv . D . valid : = slvDValid
val slvDDat = Reg ( UInt ( 32. W ) )
2023-06-30 20:21:03 +08:00
2023-10-08 18:27:49 +08:00
when ( io . tlSlv . D . fire ) {
slvDValid : = false . B
} . elsewhen ( io . tlSlv . A . fire ) {
slvDValid : = true . B
slvDDat : = bd_ram . io . dato
}
2023-07-03 16:25:41 +08:00
2023-10-08 18:27:49 +08:00
when ( slvAInfo . opcode === 4. U ) {
io . tlSlv . D . bits : = edgeIn . AccessAck ( slvAInfo , slvDDat )
} . otherwise {
io . tlSlv . D . bits : = edgeIn . AccessAck ( slvAInfo )
}
2023-06-29 18:29:54 +08:00
2023-10-08 18:27:49 +08:00
io . tlSlv . A . ready : = RegNext ( stateNxt === StateWB & Mux ( stateCur === StateWB , BDWrite . orR , BDRead ) )
assert ( ~ ( io . tlSlv . A . ready & ~ io . tlSlv . A . valid ) )
2023-07-04 17:37:41 +08:00
2023-07-07 21:43:06 +08:00
val mstAValid = RegInit ( false . B )
val mstABits = Reg ( new TLBundleA ( edgeOut . bundle ) )
2023-07-11 17:38:18 +08:00
when ( io . tlMst . A . fire ) {
2023-07-07 21:43:06 +08:00
mstAValid : = false . B
}
. elsewhen ( MasterWbTX & ~ isTlMstBusy ) {
mstAValid : = true . B
mstABits : =
edgeOut . Get (
fromSource = 0. U ,
2023-07-11 00:00:26 +08:00
toAddress = TxPointerMSB << 2 ,
2023-07-07 21:43:06 +08:00
lgSize = log2Ceil ( 32 / 8 ) . U ,
) . _2
}
2023-07-11 17:38:18 +08:00
when ( io . tlMst . A . fire ) {
2023-07-07 21:43:06 +08:00
isTlMstBusy : = true . B
2023-07-11 17:38:18 +08:00
} . elsewhen ( io . tlMst . D . fire ) {
2023-07-07 21:43:06 +08:00
isTlMstBusy : = false . B
}
2023-10-11 18:48:05 +08:00
when ( ~ MasterWbTX ) {
when ( ReadTxDataFromMemory_2 ) {
2023-07-07 21:43:06 +08:00
MasterWbTX : = true . B
}
2023-10-11 18:48:05 +08:00
} . elsewhen ( MasterWbTX ) { //1 A + 1.4D memory to fifo
2023-07-11 17:38:18 +08:00
when ( io . tlMst . D . fire & isLastD & ~ ReadTxDataFromMemory_2 ) {
2023-07-07 21:43:06 +08:00
MasterWbTX : = false . B
}
}
2023-07-11 17:38:18 +08:00
when ( io . tlMst . D . fire & io . tlMst . D . bits . opcode === 1. U ) { assert ( MasterWbTX ) }
2023-07-07 21:43:06 +08:00
2023-10-08 18:27:49 +08:00
val tlMstAValid_dbg = RegInit ( true . B )
io . tlMst . A . valid : = mstAValid & tlMstAValid_dbg
io . tlMst . A . bits : = mstABits
2023-07-07 21:43:06 +08:00
2023-10-08 18:27:49 +08:00
val tlMstDReady = RegInit ( true . B )
2023-07-11 00:00:26 +08:00
2023-10-08 18:27:49 +08:00
io . tlMst . D . ready : = tlMstDReady
2023-07-07 21:43:06 +08:00
2023-10-07 16:44:13 +08:00
}
2023-06-29 18:29:54 +08:00
2023-10-07 16:44:13 +08:00
2023-10-08 15:37:54 +08:00
class MacTileLink ( edgeIn : TLEdgeIn , edgeOut : TLEdgeOut ) extends MacTileLinkBase ( edgeIn , edgeOut )
2023-10-07 16:44:13 +08:00
2023-06-28 23:43:03 +08:00