{-# LANGUAGE ScopedTypeVariables, NumericUnderscores, PartialTypeSignatures #-}
{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
module RetroClash.Clock
    ( HzToPeriod

    , Seconds
    , Milliseconds
    , Microseconds
    , Nanoseconds
    , Picoseconds

    , ClockDivider
    , risePeriod
    , riseRate
    ) where

import Clash.Prelude

#if MIN_VERSION_clash_prelude(1,9,0)
#else
type HzToPeriod (rate :: Nat) = Seconds 1 `Div` rate

type Seconds      (s  :: Nat) = Milliseconds (1_000 * s)
type Milliseconds (ms :: Nat) = Microseconds (1_000 * ms)
type Microseconds (us :: Nat) = Nanoseconds  (1_000 * us)
type Nanoseconds  (ns :: Nat) = Picoseconds  (1_000 * ns)
type Picoseconds  (ps :: Nat) = ps

type ClockDivider dom ps = ps `Div` DomainPeriod dom
#endif

risePeriod
    :: forall ps dom. (HiddenClockResetEnable dom, _)
    => SNat ps
    -> Signal dom Bool
risePeriod :: SNat ps -> Signal dom Bool
risePeriod SNat ps
_ = SNat (Div ps (DomainConfigurationPeriod (KnownConf dom)))
-> Signal dom Bool
forall (dom :: Domain) (n :: Natural).
HiddenClockResetEnable dom =>
SNat n -> Signal dom Bool
riseEvery (forall (n :: Natural). KnownNat n => SNat n
SNat @(ClockDivider dom ps))

riseRate
    :: forall rate dom. (HiddenClockResetEnable dom, _)
    => SNat rate
    -> Signal dom Bool
riseRate :: SNat rate -> Signal dom Bool
riseRate SNat rate
_ = SNat (Div (Picoseconds 1000000000000) rate) -> Signal dom Bool
forall (ps :: Natural) (dom :: Domain).
((HiddenClock dom, HiddenReset dom, HiddenEnable dom),
 Assert
   (OrdCond
      (CmpNat 1 (DomainConfigurationPeriod (KnownConf dom)))
      'True
      'True
      'False)
   (TypeError ...)
 ~ (() :: Constraint),
 KnownNat ps) =>
SNat ps -> Signal dom Bool
risePeriod (forall (n :: Natural). KnownNat n => SNat n
SNat @(HzToPeriod rate))