Skip to content

Commit

Permalink
tie up case
Browse files Browse the repository at this point in the history
Co-authored-by: Martijn Bastiaan <[email protected]>

Co-authored-by: Martijn Bastiaan <[email protected]>

Co-authored-by: Martijn Bastiaan <[email protected]>

Co-authored-by: Martijn Bastiaan <[email protected]>

Co-authored-by: Martijn Bastiaan <[email protected]>

Maybe in place of enable, stylistic changes
  • Loading branch information
vmchale committed May 6, 2022
1 parent cee9680 commit f9deb1d
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 48 deletions.
1 change: 1 addition & 0 deletions clash-cores/clash-cores.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ test-suite unittests

build-depends:
clash-cores,
clash-lib,
tasty >= 1.2 && < 1.3,
tasty-hunit,
tasty-quickcheck,
Expand Down
61 changes: 27 additions & 34 deletions clash-cores/src/Clash/Cores/Xilinx/DcFifo/Explicit.hs
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,12 @@ dcFifo ::
Reset read ->

-- | Write data
Signal write (BitVector n) ->
-- | Write enable
Signal write Bool ->
Signal write (Maybe (BitVector n)) ->
-- | Read enable
Signal read Bool ->
XilinxFifo read write depth n
dcFifo dcCfg wClk rClk rst writeData wEnable rEnable =
let (wRst, f, wCnt, rRst, e, rCnt, rData) = dcFifo# dcCfg wClk rClk rst writeData wEnable rEnable
dcFifo dcCfg wClk rClk rst writeData rEnable =
let (wRst, f, wCnt, rRst, e, rCnt, rData) = dcFifo# dcCfg wClk rClk rst writeData rEnable
in XilinxFifo wRst f wCnt rRst e rCnt rData

dcFifo# ::
Expand All @@ -140,9 +138,7 @@ dcFifo# ::
Clock write -> Clock read -> Reset read ->

-- | Write data
Signal write (BitVector n) ->
-- | Write enable
Signal write Bool ->
Signal write (Maybe (BitVector n)) ->
-- | Read enable
Signal read Bool ->
( Signal write ResetBusy
Expand All @@ -154,10 +150,10 @@ dcFifo# ::
, Signal read (DataCount depth)
, Signal read (BitVector n)
)
dcFifo# DcConfig{..} wClk rClk rst writeData wEnable rEnable =
dcFifo# DcConfig{..} wClk rClk rst writeData rEnable =
let
(wRstBusy, wFull, wCnt, rRstBusy, rEmpty, rCnt, rData) =
go rstSignalR rstSignalW start wEnable rEnable writeData
go initState rstSignalR rEnable rstSignalW writeData
in
( wRstBusy
, wFull
Expand All @@ -180,13 +176,11 @@ dcFifo# DcConfig{..} wClk rClk rst writeData wEnable rEnable =
-- https://github.com/clash-lang/clash-compiler/blob/ea114d8edd6a110f72d148203b9db2454cae8f37/clash-prelude/src/Clash/Explicit/BlockRam.hs#L1276-L1280

go ::
Signal read Bool ->
Signal write Bool ->

FifoState n ->
Signal write Bool ->
Signal read Bool ->
Signal write (BitVector n) ->
Signal read Bool -> -- reset
Signal read Bool -> -- read enabled
Signal write Bool -> -- reset
Signal write (Maybe (BitVector n)) -> -- write data
( Signal write ResetBusy
, Signal write Full
, Signal write (DataCount depth)
Expand All @@ -196,56 +190,55 @@ dcFifo# DcConfig{..} wClk rClk rst writeData wEnable rEnable =
, Signal read (DataCount depth)
, Signal read (BitVector n)
)
go rstR rstW st@(FifoState _ rt) wEna rEna =
go st@(FifoState _ rt) rstR rEna rstW =
if rt < tWr
then goRead rstR rstW st wEna rEna
else goWrite rstR rstW st wEna rEna
then goRead st rstR rEna rstW
else goWrite st rstR rEna rstW
-- TODO: goBoth case?

goWrite rstR (True :- rstWNext) (FifoState _ rt) (_ :- wEna) rEna (_ :- wData) =
goWrite (FifoState _ rt) rstR rEna (True :- rstWNext) (_ :- wData) =
(1 :- wRstBusy, 0 :- preFull, 0 :- preWCnt, rRstBusy, fifoEmpty, rCnt, rData)
where
(wRstBusy, preFull, preWCnt, rRstBusy, fifoEmpty, rCnt, rData) =
go rstR rstWNext (FifoState mempty (rt-tWr)) wEna rEna wData
go (FifoState mempty (rt-tWr)) rstR rEna rstWNext wData

goWrite rstR (_ :- rstW) (FifoState q rt) wEna rEna wData =
goWrite (FifoState q rt) rstR rEna (_ :- rstW) wDats0 =
(0 :- wRstBusy, full, wCnt, rRstBusy, fifoEmpty, rCnt, rData)
where
(wRstBusy, preFull, preWCnt, rRstBusy, fifoEmpty, rCnt, rData) =
go rstR rstW (FifoState q' (rt-tWr)) wEna' rEna wData'
go (FifoState q' (rt-tWr)) rstR rEna rstW wDats1

wCnt = sDepth q :- preWCnt
full = (if Seq.length q == rD then high else low) :- preFull
(en :- wEna') = wEna
(wDatum :- wData') = wData
(wDat :- wDats1) = wDats0
q' =
if Seq.length q + 1 <= rD && en
then wDatum Seq.<| q
else q
case wDat of
Nothing -> q
Just x -> if Seq.length q + 1 <= rD then x Seq.<| q else q

sDepth = fromIntegral . Seq.length

goRead (rstR :- rstRNext) rstW (FifoState q rt) wEna rEna wData =
goRead (FifoState q rt) (rstR :- rstRNext) rEnas0 rstW wData =
(wRstBusy, full, wCnt, (if rstR then 1 else 0) :- rRstBusy, fifoEmpty, rCnt, rData)
where
rCnt = sDepth q :- preRCnt
fifoEmpty = (if Seq.length q == 0 then high else low) :- preEmpty
rData = nextData :- preRData

(wRstBusy, full, wCnt, rRstBusy, preEmpty, preRCnt, preRData) =
go rstRNext rstW (FifoState q' (rt+tR)) wEna rEna' wData
go (FifoState q' (rt+tR)) rstRNext rEnas1 rstW wData

(en :- rEna') = rEna
(rEna :- rEnas1) = rEnas0
(q', nextData) =
if en && not rstR
if rEna && not rstR
then
case Seq.viewr q of
Seq.EmptyR -> (q, deepErrorX "FIFO empty")
qData Seq.:> qDatum -> (qData, qDatum)
else (q, deepErrorX "Enable off or resetting")

start :: FifoState n
start = FifoState Seq.empty 0
initState :: FifoState n
initState = FifoState Seq.empty 0

tWr = snatToNum @Int (clockPeriod @write)
tR = snatToNum @Int (clockPeriod @read)
Expand Down
31 changes: 17 additions & 14 deletions clash-cores/test/Test/Cores/Xilinx/DcFifo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import Control.Monad (replicateM)

import Clash.Explicit.Prelude
import Clash.Cores.Xilinx.DcFifo.Explicit
import Clash.Netlist.Util (orNothing)


import qualified Hedgehog.Gen as Gen
import qualified Hedgehog.Range as Range
Expand All @@ -18,7 +20,7 @@ import Test.Tasty (TestTree)

tests :: TestTree
tests = testPropertyNamed
"FIFO doesn't lose any data"
"FIFO doesn't lose any data with small stalls"
"prop_fifo"
prop_fifo

Expand All @@ -34,12 +36,13 @@ intersperseStalls [] _ = []
prop_fifo :: Property
prop_fifo = property $ do
xs <- fmap Just <$> forAll (replicateM 10 genData)
stallRead <- forAll (Gen.maybe (Gen.int (Range.linear 0 10)))
stallWrite <- forAll (Gen.maybe (Gen.int (Range.linear 0 10)))
let iWrites = case stallRead of
-- TODO: stall one by 9, get overflow!
stallRead <- forAll (Gen.maybe (Gen.int (Range.linear 0 8)))
stallWrite <- forAll (Gen.maybe (Gen.int (Range.linear 0 8)))
let iWrites = case stallWrite of
Nothing -> []
Just i -> P.replicate i Nothing
let readStalls = case stallWrite of
let readStalls = case stallRead of
Nothing -> [False]
Just i -> False : L.replicate i True
throughFifo (intersperseStalls xs iWrites) (cycle readStalls) === catMaybes xs
Expand All @@ -56,7 +59,7 @@ takeState (_, _:stalls) (1, _, _, _) = ((False, stalls), (Nothing, False))
takeState (readLastCycle, True:stalls) (_, _, _, d) =
((False, stalls), (nextData, False))
where
nextData = if readLastCycle then Just d else Nothing
nextData = readLastCycle `orNothing` d
takeState (readLastCycle, _:stalls) (_, fifoEmpty, _, d) =
((readThisCycle, stalls), (nextData, readThisCycle))
where
Expand All @@ -66,14 +69,14 @@ takeState (readLastCycle, _:stalls) (_, fifoEmpty, _, d) =
feedState ::
[Maybe (BitVector 32)] ->
(ResetBusy, Full, DataCount 4) ->
([Maybe (BitVector 32)], (BitVector 32, Bool))
feedState xs (1, _, _) = (xs, (deepErrorX "Resetting", False))
feedState [] _ = ([], (deepErrorX "No more data", False))
feedState (Nothing:xs) (_, _, _) = (xs, (deepErrorX "Stall simulation", False))
([Maybe (BitVector 32)], Maybe (BitVector 32))
feedState xs (1, _, _) = (xs, Nothing)
feedState [] _ = ([], Nothing)
feedState (Nothing:xs) (_, _, _) = (xs, Nothing)
feedState (Just x:xs) (_, full, _) =
if full == high
then (Just x:xs, (deepErrorX "FIFO full, waiting", False))
else (xs, (x, True))
then (Just x:xs, Nothing)
else (xs, Just x)

throughFifo
:: [Maybe (BitVector 32)] -- ^ Write data ('Nothing' for stalls)
Expand All @@ -84,7 +87,7 @@ throughFifo wrDataList rdStalls = rdDataList
clk = clockGen @System
rst = resetGen @System
ena = enableGen @System
(wrData, wrEna) =
wrData =
mealyB clk rst ena feedState wrDataList (wrRstBusy, wrFull, wrCnt)
(rdDataMaybe, rdEna) =
mealyB clk rst ena takeState (False, rdStalls) (rdRstBusy, rdEmpty, rdCnt, rdData)
Expand All @@ -95,4 +98,4 @@ throughFifo wrDataList rdStalls = rdDataList
$ bundle rdDataMaybe

(XilinxFifo wrRstBusy wrFull wrCnt rdRstBusy rdEmpty rdCnt rdData) =
dcFifo defConfig clk clk rst wrData wrEna rdEna
dcFifo defConfig clk clk rst wrData rdEna

0 comments on commit f9deb1d

Please sign in to comment.