From 90f46491bf0d870016e96faaeaf7fff31c84468f Mon Sep 17 00:00:00 2001 From: Jasper Vinkenvleugel Date: Fri, 21 Jun 2024 13:24:10 +0200 Subject: [PATCH] Explicitly make sync a Moore machine --- clash-cores/src/Clash/Cores/Sgmii/Sync.hs | 95 +++++++++------------- clash-cores/test/Test/Cores/Sgmii/Sgmii.hs | 8 +- 2 files changed, 44 insertions(+), 59 deletions(-) diff --git a/clash-cores/src/Clash/Cores/Sgmii/Sync.hs b/clash-cores/src/Clash/Cores/Sgmii/Sync.hs index f59380729c..37e6702329 100644 --- a/clash-cores/src/Clash/Cores/Sgmii/Sync.hs +++ b/clash-cores/src/Clash/Cores/Sgmii/Sync.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE OverloadedRecordDot #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ViewPatterns #-} @@ -95,16 +96,15 @@ commas = -- | State transition function for 'sync'. Takes the state as defined in -- 'SyncState', a the new incoming code group from the SerDes-block and --- returns a tuple containing the next state and the outputs as defined in --- Clause 36 of IEEE 802.3 +-- returns the next state as defined in Clause 36 of IEEE 802.3. syncT :: -- | Current state SyncState -> -- | New input codegroup BitVector 10 -> -- | New state and output tuple - (SyncState, (SyncState, BitVector 10, Bool, DataWord, Even, SyncStatus)) -syncT self@LossOfSync{..} cg = (nextState, out) + SyncState +syncT LossOfSync{..} cg = nextState where nextState | cg `notElem` commas = LossOfSync cg rd dw rxEven @@ -113,10 +113,7 @@ syncT self@LossOfSync{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Fail - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@CommaDetect1{..} cg = (nextState, out) +syncT CommaDetect1{..} cg = nextState where nextState | not (isDw dw) = LossOfSync cg rd dw rxEven @@ -125,10 +122,7 @@ syncT self@CommaDetect1{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = Even - syncStatus = Fail - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@AcquireSync1{..} cg = (nextState, out) +syncT AcquireSync1{..} cg = nextState where nextState | not (isValidDw dw) = LossOfSync cg rd dw rxEven @@ -139,10 +133,7 @@ syncT self@AcquireSync1{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Fail - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@CommaDetect2{..} cg = (nextState, out) +syncT CommaDetect2{..} cg = nextState where nextState | not (isDw dw) = LossOfSync cg rd dw rxEven @@ -151,10 +142,7 @@ syncT self@CommaDetect2{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = Even - syncStatus = Fail - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@AcquireSync2{..} cg = (nextState, out) +syncT AcquireSync2{..} cg = nextState where nextState | not (isValidDw dw) = LossOfSync cg rd dw rxEven @@ -165,10 +153,7 @@ syncT self@AcquireSync2{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Fail - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@CommaDetect3{..} cg = (nextState, out) +syncT CommaDetect3{..} cg = nextState where nextState | not (isDw dw) = LossOfSync cg rd dw rxEven @@ -177,10 +162,7 @@ syncT self@CommaDetect3{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = Even - syncStatus = Fail - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@SyncAcquired1{..} cg = (nextState, out) +syncT SyncAcquired1{..} cg = nextState where nextState | not (isValidDw dw) = SyncAcquired2 cg rd dw rxEven @@ -191,10 +173,7 @@ syncT self@SyncAcquired1{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Ok - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@SyncAcquired2{..} cg = (nextState, out) +syncT SyncAcquired2{..} cg = nextState where nextState | not (isValidDw dw) = SyncAcquired3 cg rd dw rxEven @@ -205,11 +184,8 @@ syncT self@SyncAcquired2{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Ok goodCgs = 0 - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@SyncAcquired2A{..} cg = (nextState, out) +syncT SyncAcquired2A{..} cg = nextState where nextState | not (isValidDw dw) = SyncAcquired3 cg rd dw rxEven @@ -224,11 +200,8 @@ syncT self@SyncAcquired2A{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Ok goodCgs = _goodCgs + 1 - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@SyncAcquired3{..} cg = (nextState, out) +syncT SyncAcquired3{..} cg = nextState where nextState | not (isValidDw dw) = SyncAcquired4 cg rd dw rxEven @@ -239,11 +212,8 @@ syncT self@SyncAcquired3{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Ok goodCgs = 0 - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@SyncAcquired3A{..} cg = (nextState, out) +syncT SyncAcquired3A{..} cg = nextState where nextState | not (isValidDw dw) = SyncAcquired4 cg rd dw rxEven @@ -258,11 +228,8 @@ syncT self@SyncAcquired3A{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Ok goodCgs = _goodCgs + 1 - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@SyncAcquired4{..} cg = (nextState, out) +syncT SyncAcquired4{..} cg = nextState where nextState | not (isValidDw dw) = LossOfSync cg rd dw rxEven @@ -273,11 +240,8 @@ syncT self@SyncAcquired4{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Ok goodCgs = 0 - - out = (self, _cg, _rd, _dw, rxEven, syncStatus) -syncT self@SyncAcquired4A{..} cg = (nextState, out) +syncT SyncAcquired4A{..} cg = nextState where nextState | not (isValidDw dw) = LossOfSync cg rd dw rxEven @@ -292,10 +256,31 @@ syncT self@SyncAcquired4A{..} cg = (nextState, out) (rd, dw) = ebTbDecode _rd cg rxEven = nextEven _rxEven - syncStatus = Ok goodCgs = _goodCgs + 1 - out = (self, _cg, _rd, _dw, rxEven, syncStatus) +-- | Output function for 'sync'. Takes the state as defined in 'SyncState' and +-- returns a tuple containing the outputs as defined in Clause 36 of IEEE +-- 802.3 +syncO :: + -- | Current state + SyncState -> + -- | New state and output tuple + (SyncState, BitVector 10, Bool, DataWord, Even, SyncStatus) +syncO self@LossOfSync{..} = (self, _cg, _rd, _dw, rxEven, Fail) + where + rxEven = nextEven _rxEven +syncO self@CommaDetect1{..} = (self, _cg, _rd, _dw, Even, Fail) +syncO self@AcquireSync1{..} = (self, _cg, _rd, _dw, rxEven, Fail) + where + rxEven = nextEven _rxEven +syncO self@CommaDetect2{..} = (self, _cg, _rd, _dw, Even, Fail) +syncO self@AcquireSync2{..} = (self, _cg, _rd, _dw, rxEven, Fail) + where + rxEven = nextEven _rxEven +syncO self@CommaDetect3{..} = (self, _cg, _rd, _dw, Even, Fail) +syncO self = (self, self._cg, self._rd, self._dw, rxEven, Ok) + where + rxEven = nextEven self._rxEven -- | Transition function for the inputs of 'Sgmii.pcsReceive'. This is used to -- keep a small list of "future" values for 'DataWord', such that these can @@ -342,4 +327,4 @@ sync cg1 = out $ bundle (cg2, rd, dw, rxEven, syncStatus) (_, cg2, rd, dw, rxEven, syncStatus) = - mealyB syncT (LossOfSync 0 False (Dw 0) Even) cg1 + mooreB syncT syncO (LossOfSync 0 False (Dw 0) Even) cg1 diff --git a/clash-cores/test/Test/Cores/Sgmii/Sgmii.hs b/clash-cores/test/Test/Cores/Sgmii/Sgmii.hs index 9218709162..3cf4bea934 100644 --- a/clash-cores/test/Test/Cores/Sgmii/Sgmii.hs +++ b/clash-cores/test/Test/Cores/Sgmii/Sgmii.hs @@ -50,14 +50,14 @@ syncSim :: SyncState -> C.Signal dom (C.BitVector 10) -> C.Signal dom (C.BitVector 10, Bool, C.Vec 3 DataWord, Even, SyncStatus) -syncSim s i = o +syncSim s cg1 = o where o = C.moore outputQueueT outputQueueO (C.repeat (0, False, Dw 0, Odd, Ok)) $ - C.bundle (cg, rd, dw, rxEven, syncStatus) + C.bundle (cg2, rd, dw, rxEven, syncStatus) - (_, cg, rd, dw, rxEven, syncStatus) = - C.mealyB syncT s i + (_, cg2, rd, dw, rxEven, syncStatus) = + C.mooreB syncT syncO s cg1 -- | Version of 'pcsReceive' that allows the initial state to be set via an -- input variable