Skip to content

Commit

Permalink
Correctly handle non-aligned changes in Xmit
Browse files Browse the repository at this point in the history
  • Loading branch information
jvnknvlgl committed Jul 1, 2024
1 parent 9cd52f2 commit a239e8f
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 84 deletions.
4 changes: 1 addition & 3 deletions clash-cores/src/Clash/Cores/Sgmii.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ sgmiiCdc ::
(KnownDomain dom0, KnownDomain dom1) =>
( Clock dom0 ->
Clock dom1 ->
Reset dom0 ->
Reset dom1 ->
Signal dom0 (Maybe Xmit) ->
Signal dom0 (Maybe ConfReg) ->
Signal dom1 (Maybe Xmit, Maybe ConfReg)
Expand Down Expand Up @@ -45,7 +43,7 @@ sgmiiCdc autoNegCdc clk0 clk1 rst0 rst1 txEn txEr dw1 cg1 =
pcsTransmit' = exposeClockResetEnable pcsTransmit

(xmit2, txConfReg2) =
unbundle $ autoNegCdc clk0 clk1 rst0 rst1 xmit1 txConfReg1
unbundle $ autoNegCdc clk0 clk1 xmit1 txConfReg1

(xmit1, txConfReg1) =
unbundle
Expand Down
2 changes: 1 addition & 1 deletion clash-cores/src/Clash/Cores/Sgmii/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ data SyncStatus = Ok | Fail
-- | Signal that is received by the two PCS blocks from the auto-negotiation
-- block to indicate the current state of the auto-negotiation block
data Xmit = Conf | Data | Idle
deriving (Generic, NFDataX, Eq, Show)
deriving (Generic, NFDataX, Eq, Show, BitPack)

-- The following data words are used for comparisions in 'pcsReceive', and are
-- defined here to be usable in other places as well.
Expand Down
6 changes: 0 additions & 6 deletions clash-cores/src/Clash/Cores/Sgmii/PcsReceive.hs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,6 @@ bitDifference cg0 cg1 = foldl f 0 $ map bitCoerce $ bv2v $ xor cg0 cg1
-- group and both alternative representations of the K28.5 control word or a
-- difference of between 2 and 9 bits between the code group and the expected
-- encoding of the K28.5 control word.
--
-- Remarks:
-- - Currently this function needs to re-encode the received data words to
-- be able to determine the bit difference, this is rather unecessary in
-- practice and could be resolved by determining the carrier detect status
-- at an earlier point, for example at 'Sgmii.sync'
carrierDetect ::
-- | Code group
BitVector 10 ->
Expand Down
2 changes: 1 addition & 1 deletion clash-cores/src/Clash/Cores/Sgmii/PcsTransmit.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pcsTransmit txEn txEr dw xmit txConfReg = cg
(_, txOSet) =
mealyB
orderedSetT
(Configuration Conf)
(Configuration Conf False)
(txEn, txEr, dw, xmit, txEven, cgSent)

{-# CLASH_OPAQUE pcsTransmit #-}
170 changes: 97 additions & 73 deletions clash-cores/src/Clash/Cores/Sgmii/PcsTransmit/OrderedSet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,44 @@ import Data.Maybe (fromJust, fromMaybe, isJust)
-- exeception of @TX_TEST_XMIT@, @TX_PACKET@ and @ALIGN_ERR_START@ as these
-- states do not transmit an ordered set to the code group process
data OrderedSetState
= Configuration {_xmit :: Xmit}
| IdleS {_xmit :: Xmit}
| XmitData {_xmit :: Xmit}
| StartOfPacket {_xmit :: Xmit}
| TxData {_xmit :: Xmit}
| EndOfPacketNoExt {_xmit :: Xmit}
| Epd2NoExt {_xmit :: Xmit}
| Epd3 {_xmit :: Xmit}
| EndOfPacketExt {_xmit :: Xmit}
| ExtendBy1 {_xmit :: Xmit}
| CarrierExtend {_xmit :: Xmit}
| StartError {_xmit :: Xmit}
| TxDataError {_xmit :: Xmit}
= Configuration {_xmit :: Xmit, _xmitChange :: Bool}
| IdleS {_xmit :: Xmit, _xmitChange :: Bool}
| XmitData {_xmit :: Xmit, _xmitChange :: Bool}
| StartOfPacket {_xmit :: Xmit, _xmitChange :: Bool}
| TxData {_xmit :: Xmit, _xmitChange :: Bool}
| EndOfPacketNoExt {_xmit :: Xmit, _xmitChange :: Bool}
| Epd2NoExt {_xmit :: Xmit, _xmitChange :: Bool}
| Epd3 {_xmit :: Xmit, _xmitChange :: Bool}
| EndOfPacketExt {_xmit :: Xmit, _xmitChange :: Bool}
| ExtendBy1 {_xmit :: Xmit, _xmitChange :: Bool}
| CarrierExtend {_xmit :: Xmit, _xmitChange :: Bool}
| StartError {_xmit :: Xmit, _xmitChange :: Bool}
| TxDataError {_xmit :: Xmit, _xmitChange :: Bool}
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
Bool -> Bool -> Xmit -> Even -> Bool -> Bool -> Maybe OrderedSetState
generateCg txEn txEr xmit txEven cgSent xmitChange = 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)
| xmitChange && cgSent && txEven == Odd && xmit == Conf =
Just (Configuration xmit False)
| xmitChange && cgSent && txEven == Odd && xmit == Idle =
Just (IdleS xmit False)
| xmitChange && cgSent && txEven == Odd && xmit == Data && txEn =
Just (IdleS xmit False)
| xmitChange && cgSent && txEven == Odd && xmit == Data && txEr =
Just (IdleS xmit False)
| xmitChange
&& cgSent
&& txEven
== Odd
&& xmit
== Data
&& not txEn
&& not txEr =
Just (XmitData xmit False)
| otherwise = Nothing

-- | Void function that is used to check whether @/V/@ needs to be propagated
Expand All @@ -63,63 +73,69 @@ orderedSetT self@Configuration{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState = fromMaybe self s
nextState = fromMaybe (Configuration xmit' xmitChange) s

out = (self, OSetC)
orderedSetT self@IdleS{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| xmit' == Data && cgSent && not txEn && not txEr = XmitData xmit'
| otherwise = self
| xmit' == Data && cgSent && not txEn && not txEr =
XmitData xmit' xmitChange
| otherwise = IdleS xmit' xmitChange

out = (self, OSetI)
orderedSetT self@XmitData{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| txEn && not txEr && cgSent = StartOfPacket xmit'
| txEn && txEr && cgSent = StartError xmit'
| not txEn && cgSent = XmitData xmit'
| otherwise = self
| txEn && not txEr && cgSent = StartOfPacket xmit' xmitChange
| txEn && txEr && cgSent = StartError xmit' xmitChange
| not txEn && cgSent = XmitData xmit' xmitChange
| otherwise = XmitData xmit' xmitChange

out = (self, OSetI)
orderedSetT self@StartOfPacket{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| txEn && cgSent = TxData xmit'
| not txEn && not txEr && cgSent = EndOfPacketNoExt xmit'
| not txEn && txEr && cgSent = EndOfPacketExt xmit'
| otherwise = self
| txEn && cgSent = TxData xmit' xmitChange
| not txEn && not txEr && cgSent = EndOfPacketNoExt xmit' xmitChange
| not txEn && txEr && cgSent = EndOfPacketExt xmit' xmitChange
| otherwise = StartOfPacket xmit' xmitChange

out = (self, OSetS)
orderedSetT self@TxData{..} (txEn, txEr, dw, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| txEn && cgSent = TxData xmit'
| not txEn && not txEr && cgSent = EndOfPacketNoExt xmit'
| not txEn && txEr && cgSent = EndOfPacketExt xmit'
| otherwise = self
| txEn && cgSent = TxData xmit' xmitChange
| not txEn && not txEr && cgSent = EndOfPacketNoExt xmit' xmitChange
| not txEn && txEr && cgSent = EndOfPacketExt xmit' xmitChange
| otherwise = TxData xmit' xmitChange

txOSet = void OSetD txEn txEr dw

Expand All @@ -128,50 +144,54 @@ orderedSetT self@EndOfPacketNoExt{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| cgSent = Epd2NoExt xmit'
| otherwise = self
| cgSent = Epd2NoExt xmit' xmitChange
| otherwise = EndOfPacketNoExt xmit' xmitChange

out = (self, OSetT)
orderedSetT self@Epd2NoExt{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| txEven == Odd && cgSent = XmitData xmit'
| txEven == Even && cgSent = Epd3 xmit'
| otherwise = self
| txEven == Odd && cgSent = XmitData xmit' xmitChange
| txEven == Even && cgSent = Epd3 xmit' xmitChange
| otherwise = Epd2NoExt xmit' xmitChange

out = (self, OSetR)
orderedSetT self@Epd3{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| cgSent = XmitData xmit'
| otherwise = self
| cgSent = XmitData xmit' xmitChange
| otherwise = Epd3 xmit' xmitChange

out = (self, OSetR)
orderedSetT self@EndOfPacketExt{..} (txEn, txEr, dw, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| not txEr && cgSent = ExtendBy1 xmit'
| txEr && cgSent = CarrierExtend xmit'
| otherwise = self
| not txEr && cgSent = ExtendBy1 xmit' xmitChange
| txEr && cgSent = CarrierExtend xmit' xmitChange
| otherwise = EndOfPacketExt xmit' xmitChange

txOSet = void OSetT txEn txEr dw

Expand All @@ -180,27 +200,29 @@ orderedSetT self@ExtendBy1{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| cgSent = Epd2NoExt xmit'
| otherwise = self
| cgSent = Epd2NoExt xmit' xmitChange
| otherwise = ExtendBy1 xmit' xmitChange

out = (self, OSetR)
orderedSetT self@CarrierExtend{..} (txEn, txEr, dw, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| 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
| not txEn && not txEr && cgSent = ExtendBy1 xmit' xmitChange
| txEn && txEr && cgSent = StartError xmit' xmitChange
| txEn && not txEr && cgSent = StartOfPacket xmit' xmitChange
| not txEn && txEr && cgSent = CarrierExtend xmit' xmitChange
| otherwise = CarrierExtend xmit' xmitChange

txOSet = void OSetR txEn txEr dw

Expand All @@ -209,25 +231,27 @@ orderedSetT self@StartError{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| cgSent = TxDataError xmit'
| otherwise = self
| cgSent = TxDataError xmit' xmitChange
| otherwise = StartError xmit' xmitChange

out = (self, OSetS)
orderedSetT self@TxDataError{..} (txEn, txEr, _, xmit, txEven, cgSent) =
(nextState, out)
where
xmit' = fromMaybe _xmit xmit
s = generateCg txEn txEr xmit' _xmit txEven cgSent
xmitChange = (xmit' /= _xmit) || _xmitChange
s = generateCg txEn txEr xmit' txEven cgSent xmitChange

nextState
| isJust s = fromJust s
| txEn && cgSent = TxData xmit'
| not txEn && not txEr && cgSent = EndOfPacketNoExt xmit'
| not txEn && txEr && cgSent = EndOfPacketExt xmit'
| otherwise = self
| txEn && cgSent = TxData xmit' xmitChange
| not txEn && not txEr && cgSent = EndOfPacketNoExt xmit' xmitChange
| not txEn && txEr && cgSent = EndOfPacketExt xmit' xmitChange
| otherwise = TxDataError xmit' xmitChange

out = (self, OSetV)

0 comments on commit a239e8f

Please sign in to comment.