From 9cd52f2af0c360e0c8dc96d084170ed30850d7a7 Mon Sep 17 00:00:00 2001 From: Jasper Vinkenvleugel Date: Tue, 25 Jun 2024 17:00:59 +0200 Subject: [PATCH] Plumbing to make Xmit and ConfReg Maybes --- clash-cores/src/Clash/Cores/Sgmii.hs | 10 +- clash-cores/src/Clash/Cores/Sgmii/AutoNeg.hs | 22 +- clash-cores/src/Clash/Cores/Sgmii/BitSlip.hs | 2 +- .../src/Clash/Cores/Sgmii/PcsReceive.hs | 274 ++++++++++-------- .../src/Clash/Cores/Sgmii/PcsTransmit.hs | 6 +- .../Cores/Sgmii/PcsTransmit/CodeGroup.hs | 150 +++++----- .../Cores/Sgmii/PcsTransmit/OrderedSet.hs | 227 ++++++--------- .../test/Test/Cores/Sgmii/PcsReceive.hs | 8 +- clash-cores/test/Test/Cores/Sgmii/Sgmii.hs | 22 +- 9 files changed, 363 insertions(+), 358 deletions(-) diff --git a/clash-cores/src/Clash/Cores/Sgmii.hs b/clash-cores/src/Clash/Cores/Sgmii.hs index c393fe6d87..ed2ad832d3 100644 --- a/clash-cores/src/Clash/Cores/Sgmii.hs +++ b/clash-cores/src/Clash/Cores/Sgmii.hs @@ -18,9 +18,9 @@ sgmiiCdc :: Clock dom1 -> Reset dom0 -> Reset dom1 -> - Signal dom0 Xmit -> - Signal dom0 ConfReg -> - Signal dom1 (Xmit, ConfReg) + Signal dom0 (Maybe Xmit) -> + Signal dom0 (Maybe ConfReg) -> + Signal dom1 (Maybe Xmit, Maybe ConfReg) ) -> Clock dom0 -> Clock dom1 -> @@ -49,10 +49,10 @@ sgmiiCdc autoNegCdc clk0 clk1 rst0 rst1 txEn txEr dw1 cg1 = (xmit1, txConfReg1) = unbundle - $ autoNeg' clk0 rst0 enableGen mrAdvAbility syncStatus rudi rxConfReg + $ autoNeg' clk0 rst0 enableGen confReg syncStatus rudi rxConfReg where autoNeg' = exposeClockResetEnable autoNeg - mrAdvAbility = 0b0100000000000001 + confReg = 0b0100000000000001 dw4 = (fmap . fmap) fromDw dw3 diff --git a/clash-cores/src/Clash/Cores/Sgmii/AutoNeg.hs b/clash-cores/src/Clash/Cores/Sgmii/AutoNeg.hs index dd1c98152c..b0da4f7b7d 100644 --- a/clash-cores/src/Clash/Cores/Sgmii/AutoNeg.hs +++ b/clash-cores/src/Clash/Cores/Sgmii/AutoNeg.hs @@ -30,7 +30,7 @@ data AutoNegState dom | AbilityDetect { _rudis :: Vec 3 Rudi , _rxConfRegs :: Vec 3 ConfReg - , _mrAdvAbility :: ConfReg + , _confReg :: ConfReg , _failTimer :: Timeout dom } | AcknowledgeDetect @@ -132,22 +132,21 @@ autoNegT AnEnable{..} (_, syncStatus, rudi, rxConfReg) = nextState rudis = maybe _rudis (_rudis <<+) rudi rxConfRegs = maybe _rxConfRegs (_rxConfRegs <<+) rxConfReg failTimer = if syncStatus == Fail then _failTimer + 1 else 0 -autoNegT AnRestart{..} (mrAdvAbility, syncStatus, rudi, rxConfReg) = nextState +autoNegT AnRestart{..} (confReg, syncStatus, rudi, rxConfReg) = nextState where nextState | failTimer >= timeout (Proxy @dom) = AnEnable rudis rxConfRegs (timeout (Proxy @dom) - 1) | rudi == Just Invalid = AnEnable rudis rxConfRegs failTimer | linkTimer >= timeout (Proxy @dom) = - AbilityDetect rudis rxConfRegs mrAdvAbility failTimer + AbilityDetect rudis rxConfRegs confReg failTimer | otherwise = AnRestart rudis rxConfRegs failTimer linkTimer rudis = maybe _rudis (_rudis <<+) rudi rxConfRegs = maybe _rxConfRegs (_rxConfRegs <<+) rxConfReg linkTimer = _linkTimer + 1 failTimer = if syncStatus == Fail then _failTimer + 1 else 0 -autoNegT AbilityDetect{..} (mrAdvAbility, syncStatus, rudi, rxConfReg) = - nextState +autoNegT AbilityDetect{..} (confReg, syncStatus, rudi, rxConfReg) = nextState where nextState | failTimer >= timeout (Proxy @dom) = @@ -155,14 +154,13 @@ autoNegT AbilityDetect{..} (mrAdvAbility, syncStatus, rudi, rxConfReg) = | rudi == Just Invalid = AnEnable rudis rxConfRegs failTimer | abilityMatch rudis rxConfRegs && last rxConfRegs /= 0 = AcknowledgeDetect rudis rxConfRegs txConfReg failTimer - | otherwise = AbilityDetect rudis rxConfRegs mrAdvAbility failTimer + | otherwise = AbilityDetect rudis rxConfRegs confReg failTimer rudis = maybe _rudis (_rudis <<+) rudi rxConfRegs = maybe _rxConfRegs (_rxConfRegs <<+) rxConfReg - txConfReg = replaceBit (14 :: Index 16) 0 mrAdvAbility + txConfReg = replaceBit (14 :: Index 16) 0 confReg failTimer = if syncStatus == Fail then _failTimer + 1 else 0 -autoNegT AcknowledgeDetect{..} (_, syncStatus, rudi, rxConfReg) = - nextState +autoNegT AcknowledgeDetect{..} (_, syncStatus, rudi, rxConfReg) = nextState where nextState | failTimer >= timeout (Proxy @dom) = @@ -240,7 +238,7 @@ autoNegO self@AnEnable{} = (self, Just Conf, Just 0) autoNegO self@AnRestart{} = (self, Nothing, Just 0) autoNegO self@AbilityDetect{..} = (self, Nothing, Just txConfReg) where - txConfReg = replaceBit (14 :: Index 16) 0 _mrAdvAbility + txConfReg = replaceBit (14 :: Index 16) 0 _confReg autoNegO self@AcknowledgeDetect{..} = (self, Nothing, Just txConfReg) where txConfReg = replaceBit (14 :: Index 16) 1 _txConfReg @@ -262,9 +260,9 @@ autoNeg :: -- | A new value of 'ConfReg' from 'Sgmii.pcsReceive' Signal dom (Maybe ConfReg) -> -- | Tuple containing the new value for 'Xmit' and a new 'ConfReg' - Signal dom (Xmit, ConfReg) + Signal dom (Maybe Xmit, Maybe ConfReg) autoNeg confReg syncStatus rudi rxConfReg = - bundle (regMaybe Conf xmit, regMaybe 0 txConfReg) + bundle (xmit, txConfReg) where (_, xmit, txConfReg) = mooreB diff --git a/clash-cores/src/Clash/Cores/Sgmii/BitSlip.hs b/clash-cores/src/Clash/Cores/Sgmii/BitSlip.hs index 2ae5502ec7..da2d2c8222 100644 --- a/clash-cores/src/Clash/Cores/Sgmii/BitSlip.hs +++ b/clash-cores/src/Clash/Cores/Sgmii/BitSlip.hs @@ -47,7 +47,7 @@ bitSlipT BSOk{..} cg = nextState s = resize $ _s ++# cg --- | Output state for 'bitSlip' that takes the calculated index value and +-- | Output function for 'bitSlip' that takes the calculated index value and -- rotates the state vector to create the new output value bitSlipO :: -- | Current state diff --git a/clash-cores/src/Clash/Cores/Sgmii/PcsReceive.hs b/clash-cores/src/Clash/Cores/Sgmii/PcsReceive.hs index 1688cf2e41..f0426527b0 100644 --- a/clash-cores/src/Clash/Cores/Sgmii/PcsReceive.hs +++ b/clash-cores/src/Clash/Cores/Sgmii/PcsReceive.hs @@ -6,6 +6,7 @@ module Clash.Cores.Sgmii.PcsReceive where import Clash.Cores.LineCoding8b10b import Clash.Cores.Sgmii.Common import Clash.Prelude +import Data.Maybe (fromMaybe) -- | Defines all possible valid 'checkEnd' results, as well as @None@ for no -- valid result @@ -29,24 +30,24 @@ data CheckEnd data PcsReceiveState = Init1 | Init2 - | WaitForK {_rx :: Bool} - | RxK {_rx :: Bool} - | RxCB {_rx :: Bool} - | RxCC {_rx :: Bool, _hist :: DataWord} - | RxCD {_rx :: Bool, _hist :: DataWord, _rxConfReg :: ConfReg} - | RxInvalid {_rx :: Bool} - | IdleD {_rx :: Bool} - | FalseCarrier {_rx :: Bool} - | StartOfPacket {_rx :: Bool} - | EarlyEnd {_rx :: Bool} - | TriRri {_rx :: Bool} - | TrrExtend {_rx :: Bool} - | PacketBurstRrs {_rx :: Bool} - | ExtendErr {_rx :: Bool} - | EarlyEndExt {_rx :: Bool} - | RxData {_rx :: Bool, _hist :: DataWord} - | RxDataError {_rx :: Bool, _hist :: DataWord} - | LinkFailed {_rx :: Bool} + | WaitForK {_rx :: Bool, _xmit :: Xmit} + | RxK {_rx :: Bool, _xmit :: Xmit} + | RxCB {_rx :: Bool, _xmit :: Xmit} + | RxCC {_rx :: Bool, _xmit :: Xmit, _hist :: DataWord} + | RxCD {_rx :: Bool, _xmit :: Xmit, _hist :: DataWord, _rxConfReg :: ConfReg} + | RxInvalid {_rx :: Bool, _xmit :: Xmit} + | IdleD {_rx :: Bool, _xmit :: Xmit} + | FalseCarrier {_rx :: Bool, _xmit :: Xmit} + | StartOfPacket {_rx :: Bool, _xmit :: Xmit} + | EarlyEnd {_rx :: Bool, _xmit :: Xmit} + | TriRri {_rx :: Bool, _xmit :: Xmit} + | TrrExtend {_rx :: Bool, _xmit :: Xmit} + | PacketBurstRrs {_rx :: Bool, _xmit :: Xmit} + | ExtendErr {_rx :: Bool, _xmit :: Xmit} + | EarlyEndExt {_rx :: Bool, _xmit :: Xmit} + | RxData {_rx :: Bool, _xmit :: Xmit, _hist :: DataWord} + | RxDataError {_rx :: Bool, _xmit :: Xmit, _hist :: DataWord} + | LinkFailed {_rx :: Bool, _xmit :: Xmit} deriving (Generic, NFDataX, Eq, Show) -- | Calculate the number of bits that are different in two code groups. For @@ -133,7 +134,7 @@ pcsReceiveT :: PcsReceiveState -> -- | Input values, where @Vec 3 CodeGroup@ contains the current and next two -- | data words - (BitVector 10, Bool, Vec 3 DataWord, Even, SyncStatus, Xmit) -> + (BitVector 10, Bool, Vec 3 DataWord, Even, SyncStatus, Maybe Xmit) -> -- | Tuple with the new state and the output values ( PcsReceiveState , ( PcsReceiveState @@ -151,72 +152,78 @@ pcsReceiveT self@Init1 _ = (nextState, out) out = (self, Nothing, Nothing, Nothing, Nothing, Nothing) pcsReceiveT self@Init2 _ = (nextState, out) where - nextState = WaitForK False + nextState = WaitForK False Conf out = (self, Nothing, Nothing, Nothing, Nothing, Nothing) -pcsReceiveT self@WaitForK{} (_, _, dws, rxEven, syncStatus, _) = +pcsReceiveT self@WaitForK{..} (_, _, dws, rxEven, syncStatus, xmit) = (nextState, out) where nextState - | syncStatus == Fail = LinkFailed rx - | head dws == cwK28_5 && rxEven == Even = RxK rx + | syncStatus == Fail = LinkFailed rx xmit' + | head dws == cwK28_5 && rxEven == Even = RxK rx xmit' | otherwise = self rx = False + xmit' = fromMaybe _xmit xmit rxDv = Just False rxEr = Just False out = (self, rxDv, rxEr, Nothing, Nothing, Nothing) -pcsReceiveT self@RxK{} (_, _, dws, _, syncStatus, xmit) = (nextState, out) +pcsReceiveT self@RxK{..} (_, _, dws, _, syncStatus, xmit) = (nextState, out) where nextState - | syncStatus == Fail = LinkFailed rx - | dw == dwD21_5 = RxCB rx - | dw == dwD02_2 = RxCB rx - | not (isDw dw) && xmit /= Data = RxInvalid rx - | xmit /= Data && isDw dw = IdleD rx - | xmit == Data = IdleD rx + | syncStatus == Fail = LinkFailed rx xmit' + | dw == dwD21_5 = RxCB rx xmit' + | dw == dwD02_2 = RxCB rx xmit' + | not (isDw dw) && xmit' /= Data = RxInvalid rx xmit' + | xmit' /= Data && isDw dw = IdleD rx xmit' + | xmit' == Data = IdleD rx xmit' | otherwise = self rx = False + xmit' = fromMaybe _xmit xmit dw = head dws rxDv = Just False rxEr = Just False out = (self, rxDv, rxEr, Nothing, Nothing, Nothing) -pcsReceiveT self@RxCB{..} (_, _, dws, _, syncStatus, _) = (nextState, out) +pcsReceiveT self@RxCB{..} (_, _, dws, _, syncStatus, xmit) = (nextState, out) where nextState - | syncStatus == Fail = LinkFailed _rx - | isDw dw = RxCC _rx dw - | not (isDw dw) = RxInvalid _rx + | syncStatus == Fail = LinkFailed _rx xmit' + | isDw dw = RxCC _rx xmit' dw + | not (isDw dw) = RxInvalid _rx xmit' | otherwise = self + xmit' = fromMaybe _xmit xmit dw = head dws rxDv = Just False rxEr = Just False out = (self, rxDv, rxEr, Nothing, Nothing, Nothing) -pcsReceiveT self@RxCC{..} (_, _, dws, _, syncStatus, _) = (nextState, out) +pcsReceiveT self@RxCC{..} (_, _, dws, _, syncStatus, xmit) = (nextState, out) where nextState - | syncStatus == Fail = LinkFailed _rx - | isDw dw = RxCD _rx dw $ resize $ fromDw _hist - | not (isDw dw) = RxInvalid _rx + | syncStatus == Fail = LinkFailed _rx xmit' + | isDw dw = RxCD _rx xmit' dw $ resize $ fromDw _hist + | not (isDw dw) = RxInvalid _rx xmit' | otherwise = self + xmit' = fromMaybe _xmit xmit dw = head dws out = (self, Nothing, Nothing, Nothing, Nothing, Nothing) -pcsReceiveT self@RxCD{..} (_, _, dws, rxEven, syncStatus, _) = (nextState, out) +pcsReceiveT self@RxCD{..} (_, _, dws, rxEven, syncStatus, xmit) = + (nextState, out) where nextState - | syncStatus == Fail = LinkFailed _rx - | dw == cwK28_5 && rxEven == Even = RxK _rx - | dw /= cwK28_5 = RxInvalid _rx - | rxEven == Odd = RxInvalid _rx + | syncStatus == Fail = LinkFailed _rx xmit' + | dw == cwK28_5 && rxEven == Even = RxK _rx xmit' + | dw /= cwK28_5 = RxInvalid _rx xmit' + | rxEven == Odd = RxInvalid _rx xmit' | otherwise = self + xmit' = fromMaybe _xmit xmit dw = head dws rudi = Just C rxConfReg = (fromDw _hist ++# 0) .|. _rxConfReg @@ -226,198 +233,210 @@ pcsReceiveT self@RxInvalid{..} (_, _, dws, rxEven, syncStatus, xmit) = (nextState, out) where nextState - | syncStatus == Fail = LinkFailed rx - | dw == cwK28_5 && rxEven == Even = RxK rx - | dw /= cwK28_5 && rxEven == Even = WaitForK rx + | syncStatus == Fail = LinkFailed rx xmit' + | dw == cwK28_5 && rxEven == Even = RxK rx xmit' + | dw /= cwK28_5 && rxEven == Even = WaitForK rx xmit' | otherwise = self - rx = xmit == Data || _rx + rx = xmit' == Data || _rx + xmit' = fromMaybe _xmit xmit dw = head dws - rudi = if xmit == Conf then Just Invalid else Nothing + rudi = if xmit' == Conf then Just Invalid else Nothing out = (self, Nothing, Nothing, Nothing, rudi, Nothing) -pcsReceiveT self@IdleD{} (cg, rd, dws, rxEven, syncStatus, xmit) = +pcsReceiveT self@IdleD{..} (cg, rd, dws, rxEven, syncStatus, xmit) = (nextState, out) where carrierDetected = carrierDetect cg rd rxEven nextState - | syncStatus == Fail = LinkFailed rx - | dw /= cwK28_5 && xmit /= Data = RxInvalid rx - | carrierDetected && xmit == Data && dw /= cwS = - FalseCarrier rx - | carrierDetected && xmit == Data && dw == cwS = - StartOfPacket rx - | not carrierDetected && xmit == Data = RxK rx - | dw == cwK28_5 = RxK rx + | syncStatus == Fail = LinkFailed rx xmit' + | dw /= cwK28_5 && xmit' /= Data = RxInvalid rx xmit' + | carrierDetected && xmit' == Data && dw /= cwS = + FalseCarrier rx xmit' + | carrierDetected && xmit' == Data && dw == cwS = + StartOfPacket rx xmit' + | not carrierDetected && xmit' == Data = RxK rx xmit' + | dw == cwK28_5 = RxK rx xmit' | otherwise = self rx = False + xmit' = fromMaybe _xmit xmit dw = head dws rxDv = Just False rxEr = Just False rudi = Just I out = (self, rxDv, rxEr, Nothing, rudi, Nothing) -pcsReceiveT self@FalseCarrier{} (_, _, dws, rxEven, syncStatus, _) = +pcsReceiveT self@FalseCarrier{..} (_, _, dws, rxEven, syncStatus, xmit) = (nextState, out) where nextState - | syncStatus == Fail = LinkFailed rx - | dw == cwK28_5 && rxEven == Even = RxK rx + | syncStatus == Fail = LinkFailed rx xmit' + | dw == cwK28_5 && rxEven == Even = RxK rx xmit' | otherwise = self rx = True + xmit' = fromMaybe _xmit xmit dw = head dws rxEr = Just True out = (self, Nothing, rxEr, Just $ Cw 0b00001110, Nothing, Nothing) -pcsReceiveT self@StartOfPacket{} (_, _, dws, rxEven, syncStatus, _) = +pcsReceiveT self@StartOfPacket{..} (_, _, dws, rxEven, syncStatus, xmit) = (nextState, out) where rxEnd = checkEnd dws nextState - | syncStatus == Fail = LinkFailed rx - | rxEnd == Just K28_5DK28_5 && rxEven == Even = EarlyEnd rx - | rxEnd == Just K28_5D21_5D00_0 && rxEven == Even = EarlyEnd rx - | rxEnd == Just K28_5D02_2D00_0 && rxEven == Even = EarlyEnd rx - | rxEnd == Just TRK28_5 && rxEven == Even = TriRri rx - | rxEnd == Just TRR = TrrExtend rx - | rxEnd == Just RRR = EarlyEnd rx - | isDw dw = RxData rx dw - | otherwise = RxDataError rx dw + | syncStatus == Fail = LinkFailed rx xmit' + | rxEnd == Just K28_5DK28_5 && rxEven == Even = EarlyEnd rx xmit' + | rxEnd == Just K28_5D21_5D00_0 && rxEven == Even = EarlyEnd rx xmit' + | rxEnd == Just K28_5D02_2D00_0 && rxEven == Even = EarlyEnd rx xmit' + | rxEnd == Just TRK28_5 && rxEven == Even = TriRri rx xmit' + | rxEnd == Just TRR = TrrExtend rx xmit' + | rxEnd == Just RRR = EarlyEnd rx xmit' + | isDw dw = RxData rx xmit' dw + | otherwise = RxDataError rx xmit' dw rx = True + xmit' = fromMaybe _xmit xmit dw = head dws rxDv = Just True rxEr = Just False out = (self, rxDv, rxEr, Just $ Cw 0b01010101, Nothing, Nothing) -pcsReceiveT self@EarlyEnd{..} (_, _, dws, _, syncStatus, _) = (nextState, out) +pcsReceiveT self@EarlyEnd{..} (_, _, dws, _, syncStatus, xmit) = + (nextState, out) where nextState - | syncStatus == Fail = LinkFailed _rx - | dw /= dwD21_5 && dw /= dwD02_2 = IdleD _rx - | dw == dwD02_2 = RxCB _rx - | dw == dwD21_5 = RxCB _rx + | syncStatus == Fail = LinkFailed _rx xmit' + | dw /= dwD21_5 && dw /= dwD02_2 = IdleD _rx xmit' + | dw == dwD02_2 = RxCB _rx xmit' + | dw == dwD21_5 = RxCB _rx xmit' | otherwise = self + xmit' = fromMaybe _xmit xmit dw = head dws - rxEr = Just True out = (self, Nothing, rxEr, Nothing, Nothing, Nothing) -pcsReceiveT self@TriRri{} (_, _, dws, _, syncStatus, _) = (nextState, out) +pcsReceiveT self@TriRri{..} (_, _, dws, _, syncStatus, xmit) = (nextState, out) where nextState - | syncStatus == Fail = LinkFailed rx - | head dws == cwK28_5 = RxK rx + | syncStatus == Fail = LinkFailed rx xmit' + | head dws == cwK28_5 = RxK rx xmit' | otherwise = self rx = False + xmit' = fromMaybe _xmit xmit rxDv = Just False rxEr = Just False out = (self, rxDv, rxEr, Nothing, Nothing, Nothing) -pcsReceiveT self@TrrExtend{..} (_, _, dws, rxEven, syncStatus, _) = +pcsReceiveT self@TrrExtend{..} (_, _, dws, rxEven, syncStatus, xmit) = (nextState, out) where rxEnd = checkEnd dws nextState - | syncStatus == Fail = LinkFailed _rx - | rxEnd == Just RRR = TrrExtend _rx - | rxEnd == Just RRK28_5 && rxEven == Even = TriRri _rx - | rxEnd == Just RRS = PacketBurstRrs _rx - | otherwise = ExtendErr _rx + | syncStatus == Fail = LinkFailed _rx xmit' + | rxEnd == Just RRR = TrrExtend _rx xmit' + | rxEnd == Just RRK28_5 && rxEven == Even = TriRri _rx xmit' + | rxEnd == Just RRS = PacketBurstRrs _rx xmit' + | otherwise = ExtendErr _rx xmit' + xmit' = fromMaybe _xmit xmit rxDv = Just False rxEr = Just True out = (self, rxDv, rxEr, Just $ Cw 0b00001111, Nothing, Nothing) -pcsReceiveT self@PacketBurstRrs{..} (_, _, dws, _, syncStatus, _) = +pcsReceiveT self@PacketBurstRrs{..} (_, _, dws, _, syncStatus, xmit) = (nextState, out) where nextState - | syncStatus == Fail = LinkFailed _rx - | head dws == cwS = StartOfPacket _rx + | syncStatus == Fail = LinkFailed _rx xmit' + | head dws == cwS = StartOfPacket _rx xmit' | otherwise = self + xmit' = fromMaybe _xmit xmit rxDv = Just False out = (self, rxDv, Nothing, Just $ Cw 0b00001111, Nothing, Nothing) -pcsReceiveT self@ExtendErr{..} (_, _, dws, rxEven, syncStatus, _) = +pcsReceiveT self@ExtendErr{..} (_, _, dws, rxEven, syncStatus, xmit) = (nextState, out) where rxEnd = checkEnd dws selfCond = dw /= cwS && dw /= cwK28_5 && rxEven == Even nextState - | syncStatus == Fail = LinkFailed _rx - | dw == cwS = StartOfPacket _rx - | dw == cwK28_5 && rxEven == Even = RxK _rx - | selfCond && rxEnd == Just RRR = TrrExtend _rx - | selfCond && rxEnd == Just RRK28_5 = TriRri _rx - | selfCond && rxEnd == Just RRS = PacketBurstRrs _rx + | syncStatus == Fail = LinkFailed _rx xmit' + | dw == cwS = StartOfPacket _rx xmit' + | dw == cwK28_5 && rxEven == Even = RxK _rx xmit' + | selfCond && rxEnd == Just RRR = TrrExtend _rx xmit' + | selfCond && rxEnd == Just RRK28_5 = TriRri _rx xmit' + | selfCond && rxEnd == Just RRS = PacketBurstRrs _rx xmit' | otherwise = self + xmit' = fromMaybe _xmit xmit dw = head dws rxDv = Just False out = (self, rxDv, Nothing, Just $ Cw 0b00011111, Nothing, Nothing) -pcsReceiveT self@EarlyEndExt{..} (_, _, dws, rxEven, syncStatus, _) = +pcsReceiveT self@EarlyEndExt{..} (_, _, dws, rxEven, syncStatus, xmit) = (nextState, out) where rxEnd = checkEnd dws nextState - | syncStatus == Fail = LinkFailed _rx - | rxEnd == Just RRR = TrrExtend _rx - | rxEnd == Just RRK28_5 && rxEven == Even = TriRri _rx - | rxEnd == Just RRS = PacketBurstRrs _rx - | otherwise = ExtendErr _rx + | syncStatus == Fail = LinkFailed _rx xmit' + | rxEnd == Just RRR = TrrExtend _rx xmit' + | rxEnd == Just RRK28_5 && rxEven == Even = TriRri _rx xmit' + | rxEnd == Just RRS = PacketBurstRrs _rx xmit' + | otherwise = ExtendErr _rx xmit' + xmit' = fromMaybe _xmit xmit rxEr = Just True out = (self, Nothing, rxEr, Nothing, Nothing, Nothing) -pcsReceiveT self@RxData{..} (_, _, dws, rxEven, syncStatus, _) = +pcsReceiveT self@RxData{..} (_, _, dws, rxEven, syncStatus, xmit) = (nextState, out) where rxEnd = checkEnd dws nextState - | syncStatus == Fail = LinkFailed _rx - | rxEnd == Just K28_5DK28_5 && rxEven == Even = EarlyEnd _rx - | rxEnd == Just K28_5D21_5D00_0 && rxEven == Even = EarlyEnd _rx - | rxEnd == Just K28_5D02_2D00_0 && rxEven == Even = EarlyEnd _rx - | rxEnd == Just TRK28_5 && rxEven == Even = TriRri _rx - | rxEnd == Just TRR = TrrExtend _rx - | rxEnd == Just RRR = EarlyEnd _rx - | isDw dw = RxData _rx dw - | otherwise = RxDataError _rx dw - + | syncStatus == Fail = LinkFailed _rx xmit' + | rxEnd == Just K28_5DK28_5 && rxEven == Even = EarlyEnd _rx xmit' + | rxEnd == Just K28_5D21_5D00_0 && rxEven == Even = EarlyEnd _rx xmit' + | rxEnd == Just K28_5D02_2D00_0 && rxEven == Even = EarlyEnd _rx xmit' + | rxEnd == Just TRK28_5 && rxEven == Even = TriRri _rx xmit' + | rxEnd == Just TRR = TrrExtend _rx xmit' + | rxEnd == Just RRR = EarlyEnd _rx xmit' + | isDw dw = RxData _rx xmit' dw + | otherwise = RxDataError _rx xmit' dw + + xmit' = fromMaybe _xmit xmit dw = head dws rxEr = Just False out = (self, Nothing, rxEr, Just _hist, Nothing, Nothing) -pcsReceiveT self@RxDataError{..} (_, _, dws, rxEven, syncStatus, _) = +pcsReceiveT self@RxDataError{..} (_, _, dws, rxEven, syncStatus, xmit) = (nextState, out) where rxEnd = checkEnd dws nextState - | syncStatus == Fail = LinkFailed _rx - | rxEnd == Just K28_5DK28_5 && rxEven == Even = EarlyEnd _rx - | rxEnd == Just K28_5D21_5D00_0 && rxEven == Even = EarlyEnd _rx - | rxEnd == Just K28_5D02_2D00_0 && rxEven == Even = EarlyEnd _rx - | rxEnd == Just TRK28_5 && rxEven == Even = TriRri _rx - | rxEnd == Just TRR = TrrExtend _rx - | rxEnd == Just RRR = EarlyEnd _rx - | isDw dw = RxData _rx dw - | otherwise = RxDataError _rx dw - + | syncStatus == Fail = LinkFailed _rx xmit' + | rxEnd == Just K28_5DK28_5 && rxEven == Even = EarlyEnd _rx xmit' + | rxEnd == Just K28_5D21_5D00_0 && rxEven == Even = EarlyEnd _rx xmit' + | rxEnd == Just K28_5D02_2D00_0 && rxEven == Even = EarlyEnd _rx xmit' + | rxEnd == Just TRK28_5 && rxEven == Even = TriRri _rx xmit' + | rxEnd == Just TRR = TrrExtend _rx xmit' + | rxEnd == Just RRR = EarlyEnd _rx xmit' + | isDw dw = RxData _rx xmit' dw + | otherwise = RxDataError _rx xmit' dw + + xmit' = fromMaybe _xmit xmit dw = head dws rxEr = Just True @@ -426,14 +445,15 @@ pcsReceiveT self@LinkFailed{..} (_, _, _, _, syncStatus, xmit) = (nextState, out) where nextState - | syncStatus == Fail = LinkFailed rx - | otherwise = WaitForK rx + | syncStatus == Fail = LinkFailed rx xmit' + | otherwise = WaitForK rx xmit' (rx, rxDv, rxEr) = if _rx then (False, Nothing, Just True) else (_rx, Just False, Just False) - rudi = if xmit /= Data then Just Invalid else Nothing + xmit' = fromMaybe _xmit xmit + rudi = if xmit' /= Data then Just Invalid else Nothing out = (self, rxDv, rxEr, Nothing, rudi, Nothing) @@ -453,7 +473,7 @@ pcsReceive :: -- | The current 'SyncStatus' from 'Sgmii.sync' Signal dom SyncStatus -> -- | The 'Xmit' signal from 'Sgmii.autoNeg' - Signal dom Xmit -> + Signal dom (Maybe Xmit) -> -- | Tuple containing the output values Signal dom (Maybe Bool, Maybe Bool, Maybe DataWord, Maybe Rudi, Maybe ConfReg) pcsReceive cg rd dw1 rxEven syncStatus xmit = diff --git a/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit.hs b/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit.hs index 64692ade98..ee2a1d62d3 100644 --- a/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit.hs +++ b/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit.hs @@ -19,15 +19,15 @@ pcsTransmit :: -- | The new data word that needs to be transmitted Signal dom (BitVector 8) -> -- | The 'Xmit' signal from 'Sgmii.autoNeg' - Signal dom Xmit -> + Signal dom (Maybe Xmit) -> -- | The 'ConfReg' from 'Sgmii.autoNeg' - Signal dom ConfReg -> + Signal dom (Maybe ConfReg) -> -- | The 8b/10b encoded output value Signal dom (BitVector 10) pcsTransmit txEn txEr dw xmit txConfReg = cg where (_, cg, txEven, cgSent) = - mealyB codeGroupT (SpecialGo False Even OSetC) (txOSet, dw, txConfReg) + mealyB codeGroupT (SpecialGo False 0 Even OSetC) (txOSet, dw, txConfReg) (_, txOSet) = mealyB diff --git a/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit/CodeGroup.hs b/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit/CodeGroup.hs index 8686deeb47..c0b2888504 100644 --- a/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit/CodeGroup.hs +++ b/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit/CodeGroup.hs @@ -5,24 +5,30 @@ module Clash.Cores.Sgmii.PcsTransmit.CodeGroup where import Clash.Cores.LineCoding8b10b import Clash.Cores.Sgmii.Common import Clash.Prelude +import Data.Maybe (fromMaybe) -- | State type of 'codeGroupT' as defined in IEEE 802.3 Clause 36, with the -- exception of @GENERATE_CODE_GROUPS@ and @IDLE_DISPARITY_TEST@ as these -- states does not act upon the 125 MHz @cg_timer@ timer data CodeGroupState - = SpecialGo {_rd :: Bool, _txEven :: Even, _txOSet :: OrderedSet} - | DataGo {_rd :: Bool, _txEven :: Even} - | IdleDisparityWrong {_rd :: Bool} - | IdleI1B {_rd :: Bool} - | IdleDisparityOk {_rd :: Bool} - | IdleI2B {_rd :: Bool} - | ConfigurationC1A {_rd :: Bool} - | ConfigurationC1B {_rd :: Bool} - | ConfigurationC1C {_rd :: Bool} + = SpecialGo + { _rd :: Bool + , _txConfReg :: ConfReg + , _txEven :: Even + , _txOSet :: OrderedSet + } + | DataGo {_rd :: Bool, _txConfReg :: ConfReg, _txEven :: Even} + | IdleDisparityWrong {_rd :: Bool, _txConfReg :: ConfReg} + | IdleI1B {_rd :: Bool, _txConfReg :: ConfReg} + | IdleDisparityOk {_rd :: Bool, _txConfReg :: ConfReg} + | IdleI2B {_rd :: Bool, _txConfReg :: ConfReg} + | ConfigurationC1A {_rd :: Bool, _txConfReg :: ConfReg} + | ConfigurationC1B {_rd :: Bool, _txConfReg :: ConfReg} + | ConfigurationC1C {_rd :: Bool, _txConfReg :: ConfReg} | ConfigurationC1D {_rd :: Bool, _txConfReg :: ConfReg} - | ConfigurationC2A {_rd :: Bool} - | ConfigurationC2B {_rd :: Bool} - | ConfigurationC2C {_rd :: Bool} + | ConfigurationC2A {_rd :: Bool, _txConfReg :: ConfReg} + | ConfigurationC2B {_rd :: Bool, _txConfReg :: ConfReg} + | ConfigurationC2C {_rd :: Bool, _txConfReg :: ConfReg} | ConfigurationC2D {_rd :: Bool, _txConfReg :: ConfReg} deriving (Generic, NFDataX, Eq, Show) @@ -35,17 +41,17 @@ codeGroupT :: CodeGroupState -> -- | Input 'DataWord' from the ordered set, new input value and the config -- register - (OrderedSet, BitVector 8, ConfReg) -> + (OrderedSet, BitVector 8, Maybe ConfReg) -> -- | The new state and the new output values (CodeGroupState, (CodeGroupState, BitVector 10, Even, Bool)) -codeGroupT self@SpecialGo{..} (txOSet, _, _) = (nextState, out) +codeGroupT self@SpecialGo{..} (txOSet, _, txConfReg) = (nextState, out) where nextState - | txOSet == OSetD = DataGo rd txEven - | txOSet == OSetI && rd = IdleDisparityWrong rd - | txOSet == OSetI && not rd = IdleDisparityOk rd - | txOSet == OSetC = ConfigurationC1A rd - | otherwise = SpecialGo rd txEven txOSet + | txOSet == OSetD = DataGo rd txConfReg' txEven + | txOSet == OSetI && rd = IdleDisparityWrong rd txConfReg' + | txOSet == OSetI && not rd = IdleDisparityOk rd txConfReg' + | txOSet == OSetC = ConfigurationC1A rd txConfReg' + | otherwise = SpecialGo rd txConfReg' txEven txOSet dw | _txOSet == OSetS = cwS @@ -54,136 +60,150 @@ codeGroupT self@SpecialGo{..} (txOSet, _, _) = (nextState, out) | _txOSet == OSetV = cwV | otherwise = Cw 0 + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd dw txEven = nextEven _txEven out = (self, cg, txEven, True) -codeGroupT self@DataGo{..} (txOSet, dw, _) = (nextState, out) +codeGroupT self@DataGo{..} (txOSet, dw, txConfReg) = (nextState, out) where nextState - | txOSet == OSetD = DataGo rd txEven - | txOSet == OSetI && rd = IdleDisparityWrong rd - | txOSet == OSetI && not rd = IdleDisparityOk rd - | txOSet == OSetC = ConfigurationC1A rd - | otherwise = SpecialGo rd txEven txOSet + | txOSet == OSetD = DataGo rd txConfReg' txEven + | txOSet == OSetI && rd = IdleDisparityWrong rd txConfReg' + | txOSet == OSetI && not rd = IdleDisparityOk rd txConfReg' + | txOSet == OSetC = ConfigurationC1A rd txConfReg' + | otherwise = SpecialGo rd txConfReg' txEven txOSet + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd (Dw dw) txEven = nextEven _txEven out = (self, cg, txEven, True) -codeGroupT self@IdleDisparityWrong{..} _ = (nextState, out) +codeGroupT self@IdleDisparityWrong{..} (_, _, txConfReg) = (nextState, out) where - nextState = IdleI1B rd + nextState = IdleI1B rd txConfReg' + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd cwK28_5 txEven = Even out = (self, cg, txEven, False) -codeGroupT self@IdleI1B{..} (txOSet, _, _) = (nextState, out) +codeGroupT self@IdleI1B{..} (txOSet, _, txConfReg) = (nextState, out) where nextState - | txOSet == OSetD = DataGo rd txEven - | txOSet == OSetI && rd = IdleDisparityWrong rd - | txOSet == OSetI && not rd = IdleDisparityOk rd - | txOSet == OSetC = ConfigurationC1A rd - | otherwise = SpecialGo rd txEven txOSet + | txOSet == OSetD = DataGo rd txConfReg' txEven + | txOSet == OSetI && rd = IdleDisparityWrong rd txConfReg' + | txOSet == OSetI && not rd = IdleDisparityOk rd txConfReg' + | txOSet == OSetC = ConfigurationC1A rd txConfReg' + | otherwise = SpecialGo rd txConfReg' txEven txOSet + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd dwD05_6 txEven = Odd out = (self, cg, txEven, True) -codeGroupT self@IdleDisparityOk{..} _ = (nextState, out) +codeGroupT self@IdleDisparityOk{..} (_, _, txConfReg) = (nextState, out) where - nextState = IdleI2B rd + nextState = IdleI2B rd txConfReg' + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd cwK28_5 txEven = Even out = (self, cg, txEven, False) -codeGroupT self@IdleI2B{..} (txOSet, _, _) = (nextState, out) +codeGroupT self@IdleI2B{..} (txOSet, _, txConfReg) = (nextState, out) where nextState - | txOSet == OSetD = DataGo rd txEven - | txOSet == OSetI && rd = IdleDisparityWrong rd - | txOSet == OSetI && not rd = IdleDisparityOk rd - | txOSet == OSetC = ConfigurationC1A rd - | otherwise = SpecialGo rd txEven txOSet + | txOSet == OSetD = DataGo rd txConfReg' txEven + | txOSet == OSetI && rd = IdleDisparityWrong rd txConfReg' + | txOSet == OSetI && not rd = IdleDisparityOk rd txConfReg' + | txOSet == OSetC = ConfigurationC1A rd txConfReg' + | otherwise = SpecialGo rd txConfReg' txEven txOSet + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd dwD16_2 txEven = Odd out = (self, cg, txEven, True) -codeGroupT self@ConfigurationC1A{..} _ = (nextState, out) +codeGroupT self@ConfigurationC1A{..} (_, _, txConfReg) = (nextState, out) where - nextState = ConfigurationC1B rd + nextState = ConfigurationC1B rd txConfReg' + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd cwK28_5 txEven = Even out = (self, cg, txEven, False) -codeGroupT self@ConfigurationC1B{..} _ = (nextState, out) +codeGroupT self@ConfigurationC1B{..} (_, _, txConfReg) = (nextState, out) where - nextState = ConfigurationC1C rd + nextState = ConfigurationC1C rd txConfReg' + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd dwD21_5 txEven = Odd out = (self, cg, txEven, False) codeGroupT self@ConfigurationC1C{..} (_, _, txConfReg) = (nextState, out) where - nextState = ConfigurationC1D rd txConfReg + nextState = ConfigurationC1D rd txConfReg' - (rd, cg) = encode8b10b _rd (Dw (resize txConfReg)) + txConfReg' = fromMaybe _txConfReg txConfReg + (rd, cg) = encode8b10b _rd (Dw (resize txConfReg')) txEven = Even out = (self, cg, txEven, False) -codeGroupT self@ConfigurationC1D{..} (txOSet, _, _) = (nextState, out) +codeGroupT self@ConfigurationC1D{..} (txOSet, _, txConfReg) = (nextState, out) where nextState - | txOSet == OSetD = DataGo rd txEven - | txOSet == OSetI && rd = IdleDisparityWrong rd - | txOSet == OSetI && not rd = IdleDisparityOk rd - | txOSet == OSetC = ConfigurationC2A rd - | otherwise = SpecialGo rd txEven txOSet + | txOSet == OSetD = DataGo rd txConfReg' txEven + | txOSet == OSetI && rd = IdleDisparityWrong rd txConfReg' + | txOSet == OSetI && not rd = IdleDisparityOk rd txConfReg' + | txOSet == OSetC = ConfigurationC2A rd txConfReg' + | otherwise = SpecialGo rd txConfReg' txEven txOSet + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd (Dw (resize $ rotateR _txConfReg 8)) txEven = Odd out = (self, cg, txEven, True) -codeGroupT self@ConfigurationC2A{..} _ = (nextState, out) +codeGroupT self@ConfigurationC2A{..} (_, _, txConfReg) = (nextState, out) where - nextState = ConfigurationC2B rd + nextState = ConfigurationC2B rd txConfReg' + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd cwK28_5 txEven = Even out = (self, cg, txEven, False) -codeGroupT self@ConfigurationC2B{..} _ = (nextState, out) +codeGroupT self@ConfigurationC2B{..} (_, _, txConfReg) = (nextState, out) where - nextState = ConfigurationC2C rd + nextState = ConfigurationC2C rd txConfReg' + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd dwD02_2 txEven = Odd out = (self, cg, txEven, False) codeGroupT self@ConfigurationC2C{..} (_, _, txConfReg) = (nextState, out) where - nextState = ConfigurationC2D rd txConfReg + nextState = ConfigurationC2D rd txConfReg' - (rd, cg) = encode8b10b _rd (Dw (resize txConfReg)) + txConfReg' = fromMaybe _txConfReg txConfReg + (rd, cg) = encode8b10b _rd (Dw (resize txConfReg')) txEven = Even out = (self, cg, txEven, False) -codeGroupT self@ConfigurationC2D{..} (txOSet, _, _) = +codeGroupT self@ConfigurationC2D{..} (txOSet, _, txConfReg) = (nextState, out) where nextState - | txOSet == OSetD = DataGo rd txEven - | txOSet == OSetI && rd = IdleDisparityWrong rd - | txOSet == OSetI && not rd = IdleDisparityOk rd - | txOSet == OSetC = ConfigurationC1A rd - | otherwise = SpecialGo rd txEven txOSet + | txOSet == OSetD = DataGo rd txConfReg' txEven + | txOSet == OSetI && rd = IdleDisparityWrong rd txConfReg' + | txOSet == OSetI && not rd = IdleDisparityOk rd txConfReg' + | txOSet == OSetC = ConfigurationC1A rd txConfReg' + | otherwise = SpecialGo rd txConfReg' txEven txOSet + txConfReg' = fromMaybe _txConfReg txConfReg (rd, cg) = encode8b10b _rd (Dw (resize $ rotateR _txConfReg 8)) txEven = Odd diff --git a/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit/OrderedSet.hs b/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit/OrderedSet.hs index 301078bcd4..2bcbef00e9 100644 --- a/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit/OrderedSet.hs +++ b/clash-cores/src/Clash/Cores/Sgmii/PcsTransmit/OrderedSet.hs @@ -4,6 +4,7 @@ module Clash.Cores.Sgmii.PcsTransmit.OrderedSet where import Clash.Cores.Sgmii.Common import Clash.Prelude +import Data.Maybe (fromJust, fromMaybe, isJust) -- | State type of 'orderedSetT' as defined in IEEE 802.3 Clause 36, with the -- exeception of @TX_TEST_XMIT@, @TX_PACKET@ and @ALIGN_ERR_START@ as these @@ -24,6 +25,21 @@ data OrderedSetState | TxDataError {_xmit :: Xmit} deriving (Generic, NFDataX, Eq, Show) +-- | State transitions from @GENERATE_CODE_GROUPS@ from Figure 36-6 +generateCg :: + Bool -> Bool -> Xmit -> Xmit -> Even -> Bool -> Maybe OrderedSetState +generateCg txEn txEr xmit _xmit txEven cgSent = nextState + where + xmitChange = xmit /= _xmit && cgSent && txEven == Odd + + nextState + | xmitChange && xmit == Conf = Just (Configuration xmit) + | xmitChange && xmit == Idle = Just (IdleS xmit) + | xmitChange && xmit == Data && txEn = Just (IdleS xmit) + | xmitChange && xmit == Data && txEr = Just (IdleS xmit) + | xmitChange && xmit == Data && not txEn && not txEr = Just (XmitData xmit) + | otherwise = Nothing + -- | Void function that is used to check whether @/V/@ needs to be propagated -- based on the values of the input pins void :: OrderedSet -> Bool -> Bool -> BitVector 8 -> OrderedSet @@ -40,94 +56,69 @@ orderedSetT :: OrderedSetState -> -- | The new input values, partly from the outside world, and partly from -- 'autoNeg' and 'codeGroupT' - (Bool, Bool, BitVector 8, Xmit, Even, Bool) -> + (Bool, Bool, BitVector 8, Maybe Xmit, Even, Bool) -> -- | The new state and the new output values (OrderedSetState, (OrderedSetState, OrderedSet)) orderedSetT self@Configuration{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent - nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | otherwise = self + nextState = fromMaybe self s - txOSet = OSetC - - out = (self, txOSet) + out = (self, OSetC) orderedSetT self@IdleS{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | xmit == Data && cgSent && not txEn && not txEr = XmitData xmit + | isJust s = fromJust s + | xmit' == Data && cgSent && not txEn && not txEr = XmitData xmit' | otherwise = self - txOSet = OSetI - - out = (self, txOSet) + out = (self, OSetI) orderedSetT self@XmitData{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | txEn && not txEr && cgSent = StartOfPacket xmit - | txEn && txEr && cgSent = StartError xmit - | not txEn && cgSent = XmitData xmit + | isJust s = fromJust s + | txEn && not txEr && cgSent = StartOfPacket xmit' + | txEn && txEr && cgSent = StartError xmit' + | not txEn && cgSent = XmitData xmit' | otherwise = self - txOSet = OSetI - - out = (self, txOSet) + out = (self, OSetI) orderedSetT self@StartOfPacket{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | txEn && cgSent = TxData xmit - | not txEn && not txEr && cgSent = EndOfPacketNoExt xmit - | not txEn && txEr && cgSent = EndOfPacketExt xmit + | isJust s = fromJust s + | txEn && cgSent = TxData xmit' + | not txEn && not txEr && cgSent = EndOfPacketNoExt xmit' + | not txEn && txEr && cgSent = EndOfPacketExt xmit' | otherwise = self - txOSet = OSetS - - out = (self, txOSet) + out = (self, OSetS) orderedSetT self@TxData{..} (txEn, txEr, dw, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | txEn && cgSent = TxData xmit - | not txEn && not txEr && cgSent = EndOfPacketNoExt xmit - | not txEn && txEr && cgSent = EndOfPacketExt xmit + | isJust s = fromJust s + | txEn && cgSent = TxData xmit' + | not txEn && not txEr && cgSent = EndOfPacketNoExt xmit' + | not txEn && txEr && cgSent = EndOfPacketExt xmit' | otherwise = self txOSet = void OSetD txEn txEr dw @@ -136,68 +127,50 @@ orderedSetT self@TxData{..} (txEn, txEr, dw, xmit, txEven, cgSent) = orderedSetT self@EndOfPacketNoExt{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | cgSent = Epd2NoExt xmit + | isJust s = fromJust s + | cgSent = Epd2NoExt xmit' | otherwise = self - txOSet = OSetT - - out = (self, txOSet) + out = (self, OSetT) orderedSetT self@Epd2NoExt{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | txEven == Odd && cgSent = XmitData xmit - | txEven == Even && cgSent = Epd3 xmit + | isJust s = fromJust s + | txEven == Odd && cgSent = XmitData xmit' + | txEven == Even && cgSent = Epd3 xmit' | otherwise = self - txOSet = OSetR - - out = (self, txOSet) + out = (self, OSetR) orderedSetT self@Epd3{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | cgSent = XmitData xmit + | isJust s = fromJust s + | cgSent = XmitData xmit' | otherwise = self - txOSet = OSetR - - out = (self, txOSet) + out = (self, OSetR) orderedSetT self@EndOfPacketExt{..} (txEn, txEr, dw, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | not txEr && cgSent = ExtendBy1 xmit - | txEr && cgSent = CarrierExtend xmit + | isJust s = fromJust s + | not txEr && cgSent = ExtendBy1 xmit' + | txEr && cgSent = CarrierExtend xmit' | otherwise = self txOSet = void OSetT txEn txEr dw @@ -206,35 +179,27 @@ orderedSetT self@EndOfPacketExt{..} (txEn, txEr, dw, xmit, txEven, cgSent) = orderedSetT self@ExtendBy1{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | cgSent = Epd2NoExt xmit + | isJust s = fromJust s + | cgSent = Epd2NoExt xmit' | otherwise = self - txOSet = OSetR - - out = (self, txOSet) + out = (self, OSetR) orderedSetT self@CarrierExtend{..} (txEn, txEr, dw, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | not txEn && not txEr && cgSent = ExtendBy1 xmit - | txEn && txEr && cgSent = StartError xmit - | txEn && not txEr && cgSent = StartOfPacket xmit - | not txEn && txEr && cgSent = CarrierExtend xmit + | isJust s = fromJust s + | not txEn && not txEr && cgSent = ExtendBy1 xmit' + | txEn && txEr && cgSent = StartError xmit' + | txEn && not txEr && cgSent = StartOfPacket xmit' + | not txEn && txEr && cgSent = CarrierExtend xmit' | otherwise = self txOSet = void OSetR txEn txEr dw @@ -243,36 +208,26 @@ orderedSetT self@CarrierExtend{..} (txEn, txEr, dw, xmit, txEven, cgSent) = orderedSetT self@StartError{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | cgSent = TxDataError xmit + | isJust s = fromJust s + | cgSent = TxDataError xmit' | otherwise = self - txOSet = OSetS - - out = (self, txOSet) + out = (self, OSetS) orderedSetT self@TxDataError{..} (txEn, txEr, _, xmit, txEven, cgSent) = (nextState, out) where - xmitChange = xmit /= _xmit && cgSent && txEven == Odd + xmit' = fromMaybe _xmit xmit + s = generateCg txEn txEr xmit' _xmit txEven cgSent nextState - | xmitChange && xmit == Conf = Configuration xmit - | xmitChange && xmit == Idle = IdleS xmit - | xmitChange && xmit == Data && txEn = IdleS xmit - | xmitChange && xmit == Data && txEr = IdleS xmit - | xmitChange && xmit == Data && not txEn && not txEr = XmitData xmit - | txEn && cgSent = TxData xmit - | not txEn && not txEr && cgSent = EndOfPacketNoExt xmit - | not txEn && txEr && cgSent = EndOfPacketExt xmit + | isJust s = fromJust s + | txEn && cgSent = TxData xmit' + | not txEn && not txEr && cgSent = EndOfPacketNoExt xmit' + | not txEn && txEr && cgSent = EndOfPacketExt xmit' | otherwise = self - txOSet = OSetV - - out = (self, txOSet) + out = (self, OSetV) diff --git a/clash-cores/test/Test/Cores/Sgmii/PcsReceive.hs b/clash-cores/test/Test/Cores/Sgmii/PcsReceive.hs index 6fe88de53b..a8ecf334ce 100644 --- a/clash-cores/test/Test/Cores/Sgmii/PcsReceive.hs +++ b/clash-cores/test/Test/Cores/Sgmii/PcsReceive.hs @@ -51,7 +51,7 @@ pcsReceiveSim :: , C.Vec 3 DataWord , Even , SyncStatus - , Xmit + , Maybe Xmit ) -> C.Signal dom PcsReceiveState pcsReceiveSim s i = s' @@ -71,15 +71,15 @@ prop_pcsReceiveStartOfPacket = H.property $ do C.sampleN simDuration ( pcsReceiveSim @C.System - (StartOfPacket True) + (StartOfPacket True Idle) (C.fromList (map f inp)) ) where - f (rd, dw) = (0, rd, C.repeat dw, Even, Ok, Idle) + f (rd, dw) = (0, rd, C.repeat dw, Even, Ok, Just Idle) H.assert $ isJust $ find g simOut where - g (RxData _ _) = True + g RxData{} = True g _ = False tests :: TestTree diff --git a/clash-cores/test/Test/Cores/Sgmii/Sgmii.hs b/clash-cores/test/Test/Cores/Sgmii/Sgmii.hs index 010fa06fb9..1cb7d981fd 100644 --- a/clash-cores/test/Test/Cores/Sgmii/Sgmii.hs +++ b/clash-cores/test/Test/Cores/Sgmii/Sgmii.hs @@ -27,7 +27,14 @@ import Prelude sgmiiCommon :: (C.HiddenClockResetEnable dom) => C.Signal dom (C.BitVector 10) -> - C.Signal dom (Maybe Bool, Maybe Bool, Maybe DataWord, Xmit, ConfReg) + C.Signal + dom + ( Maybe Bool + , Maybe Bool + , Maybe DataWord + , Maybe Xmit + , Maybe ConfReg + ) sgmiiCommon cg1 = C.bundle (rxDv, rxEr, dw2, xmit, txConfReg) where (xmit, txConfReg) = @@ -116,13 +123,18 @@ confRegSim confReg1 = fromMaybe 0 <$> confReg2 where (_, _, _, _, confReg2) = C.unbundle $ - pcsReceive cg2 rd dw2 rxEven1 syncStatus (pure Conf) + pcsReceive cg2 rd dw2 rxEven1 syncStatus (pure $ Just Conf) (cg2, rd, dw2, rxEven1, syncStatus) = C.unbundle $ sync cg1 cg1 = C.unbundle $ - pcsTransmit (pure False) (pure False) (pure 0) (pure Conf) confReg1 + pcsTransmit + (pure False) + (pure False) + (pure 0) + (pure $ Just Conf) + (Just <$> confReg1) -- | Test that the completely integrated system works in a loopback mode, where -- the output of the second 'sgmii' instance is connected to its own input. @@ -137,7 +149,7 @@ prop_loopbackTest = H.property $ do simDuration <- H.forAll (Gen.integral (Range.linear 1 100)) inp <- H.forAll (Gen.list (Range.singleton simDuration) genDefinedBitVector) - let setupSamples = 90 + let setupSamples = 86 delaySamples = 17 controlCount = 9 @@ -168,7 +180,7 @@ prop_duplexTransmission = H.property $ do inp1 <- H.forAll (Gen.list (Range.singleton simDuration) genDefinedBitVector) inp2 <- H.forAll (Gen.list (Range.singleton simDuration) genDefinedBitVector) - let setupSamples = 90 + let setupSamples = 86 delaySamples = 9 controlCount = 9