Permalink
Browse files

In the UART implementations, use the Clock domain to

compute the divider
  • Loading branch information...
gergoerdi committed Sep 8, 2018
1 parent cc0092c commit c1c6c5480a71b620e4b365425be6220d93f8029f
@@ -0,0 +1,13 @@
module Cactus.Clash.Clock
( clkPeriod
, clkRate
) where
import Clash.Prelude hiding (clkPeriod)
import qualified Cactus.Clash.Explicit.Clock as E
clkPeriod :: (HiddenClock domain gated, domain ~ Dom s ps, KnownNat ps) => Integer
clkPeriod = hideClock E.clkPeriod
clkRate :: (HiddenClock domain gated, domain ~ Dom s ps, KnownNat ps) => Integer
clkRate = hideClock E.clkRate
@@ -0,0 +1,18 @@
module Cactus.Clash.Explicit.Clock
( clkPeriod
, clkRate
) where
import Clash.Prelude hiding (clkPeriod)
import Clash.Signal.Internal (Clock(..))
clkPeriod :: forall s ps gated. (KnownNat ps) => Clock (Dom s ps) gated -> Integer
clkPeriod clk = snatToInteger (SNat @ps)
-- -- https://github.com/clash-lang/clash-compiler/issues/348
-- clkPeriod :: Clock dom gated -> Integer
-- clkPeriod (Clock _ period) = snatToInteger period
-- clkPeriod (GatedClock _ period _) = snatToInteger period
clkRate :: (KnownNat ps) => Clock (Dom s ps) gated -> Integer
clkRate clk = 10^12 `div` clkPeriod clk
@@ -8,6 +8,7 @@ module Cactus.Clash.SerialRX
import Clash.Prelude
import Cactus.Clash.Util
import Cactus.Clash.Clock
import GHC.Generics (Generic, Generic1)
import Control.DeepSeq
@@ -23,7 +24,7 @@ import Data.Monoid
data RXState = RXState
{ buf1, buf2 :: Bit
, cnt :: Word16
, cnt :: Word32
, byte :: Word8
, state :: MicroState
}
@@ -37,7 +38,7 @@ data MicroState
| RXCleanup
deriving (Generic, NFData, Show)
rx0 :: Word16 -> Bit -> State RXState (Maybe Word8)
rx0 :: Word32 -> Bit -> State RXState (Maybe Word8)
rx0 divider bit = do
s@RXState{..} <- get
modify $ \s -> s{ buf2 = buf1, buf1 = bit, cnt = cnt - 1 }
@@ -58,12 +59,11 @@ rx0 divider bit = do
goto st = modify $ \s -> s{ cnt = divider, state = st }
rx
:: (HiddenClockReset domain gated synchronous)
:: (HiddenClockReset domain gated synchronous, domain ~ Dom s ps, KnownNat ps)
=> Word32
-> Word32
-> Signal domain Bit
-> Signal domain (Maybe Word8)
rx clkRate serialRate = mealyState (rx0 $ fromIntegral $ clkRate `div` serialRate) s0
rx serialRate = mealyState (rx0 $ fromIntegral clkRate `div` serialRate) s0
where
s0 = RXState
{ buf1 = 0
@@ -8,6 +8,7 @@ module Cactus.Clash.SerialTX
import Clash.Prelude
import Cactus.Clash.Util
import Cactus.Clash.Clock
import Control.Category ((>>>))
import Control.Monad.State
@@ -49,14 +50,13 @@ tx0 divider v = do
put $ if cnt == 0 then (divider, s) else (cnt - 1, s0)
tx
:: (HiddenClockReset domain gated synchronous)
:: (HiddenClockReset domain gated synchronous, domain ~ Dom s ps, KnownNat ps)
=> Word32
-> Word32
-> Signal domain (Maybe Word8)
-> TXOut domain
tx clkRate serialRate inp = TXOut{..}
tx serialRate inp = TXOut{..}
where
(txReady, txOut) = unbundle $ mealyState (tx0 $ clkRate `div` serialRate) (0, Nothing) inp
(txReady, txOut) = unbundle $ mealyState (tx0 $ fromIntegral clkRate `div` serialRate) (0, Nothing) inp
fifo
:: forall domain gated synchronous a. (HiddenClockReset domain gated synchronous)
@@ -12,6 +12,8 @@ import Control.Monad
import Brainfuck.Computer
type Dom32 = Dom "CLK_32MHZ" 31250
{-# NOINLINE topEntity #-}
{-# ANN topEntity
(Synthesize
@@ -30,14 +32,14 @@ import Brainfuck.Computer
]
}) #-}
topEntity
:: Clock System Source
-> Reset System Asynchronous
-> Signal System Bit
-> Signal System (Vec 8 Bit)
-> Signal System Bit
-> ( Signal System Bit
, (Signal System (Vec 4 Bit), Signal System (Vec 7 Bit), Signal System Bit)
, Signal System (Vec 2 Bit)
:: Clock Dom32 Source
-> Reset Dom32 Asynchronous
-> Signal Dom32 Bit
-> Signal Dom32 (Vec 8 Bit)
-> Signal Dom32 Bit
-> ( Signal Dom32 Bit
, (Signal Dom32 (Vec 4 Bit), Signal Dom32 (Vec 7 Bit), Signal Dom32 Bit)
, Signal Dom32 (Vec 2 Bit)
)
topEntity = exposeClockReset board
where
@@ -57,9 +59,9 @@ topEntity = exposeClockReset board
ackOutput = click .&&. fifoReady
input = mplus <$> (enable <$> click <*> rawInput) <*> serialIn
serialIn = rx clkRate serialRate recv
serialIn = rx serialRate recv
TXOut{..} = tx clkRate serialRate output'
TXOut{..} = tx serialRate output'
(output', fifoReady) = fifo (diff output) txReady
(output, needInput, cpuState) = computer "prog.rom" input ackOutput
@@ -77,8 +79,5 @@ topEntity = exposeClockReset board
noSegs = pure (repeat low)
clkRate :: Word32
clkRate = 32000000
serialRate :: Word32
serialRate = 9600
@@ -8,7 +8,7 @@ clashProject = ClashProject
, topName = "Top"
, ipCores = []
, vhdlSrcs = ["Top"]
, clashFlags = ["-i../../lib/src-clash"]
, clashFlags = ["-i../../lib/src-clash", "-Wno-partial-type-signatures"]
, shakeDir = "../../shake"
}
@@ -1,13 +1,17 @@
{-# LANGUAGE RecordWildCards, TupleSections #-}
{-# LANGUAGE PartialTypeSignatures #-}
module Serial where
import Clash.Prelude
import Clash.Prelude hiding (clkPeriod)
import Cactus.Clash.Util
import Cactus.Clash.SevenSegment
import Cactus.Clash.SerialTX
import Cactus.Clash.SerialRX
import Data.Word
import Data.Maybe (fromMaybe, isJust)
import Data.Proxy
type Dom32 = Dom "CLK_32MHZ" 31250
{-# NOINLINE topEntity #-}
{-# ANN topEntity
@@ -26,13 +30,13 @@ import Data.Maybe (fromMaybe, isJust)
]
}) #-}
topEntity
:: Clock System Source
-> Reset System Asynchronous
-> Signal System Bit
-> Signal System (Vec 8 Bit)
-> Signal System Bit
-> ( Signal System Bit
, (Signal System (Vec 4 Bit), Signal System (Vec 7 Bit), Signal System Bit)
:: Clock Dom32 Source
-> Reset _ Asynchronous
-> Signal _ Bit
-> Signal _ (Vec 8 Bit)
-> Signal _ Bit
-> ( Signal _ Bit
, (Signal _ (Vec 4 Bit), Signal _ (Vec 7 Bit), Signal _ Bit)
)
topEntity = exposeClockReset board
where
@@ -49,10 +53,10 @@ topEntity = exposeClockReset board
rawOutput = unpack . v2bv <$> switches
output = gate <$> click <*> rawOutput
TXOut{..} = tx clkRate serialRate output'
TXOut{..} = tx serialRate output'
(output', fifoReady) = fifo (diff output) txReady
input = regMaybe 0 $ rx clkRate serialRate rxIn
input = regMaybe 0 $ rx serialRate rxIn
-- input = pure 0
(ihi, ilo) = unbundle $ splitByte <$> input
@@ -72,8 +76,5 @@ gate :: Bool -> a -> Maybe a
gate False = const Nothing
gate True = Just
clkRate :: Word32
clkRate = 32000000
serialRate :: Word32
serialRate = 9600

0 comments on commit c1c6c54

Please sign in to comment.