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

    , Seconds
    , Milliseconds
    , Microseconds
    , Nanoseconds
    , Picoseconds

    , ClockDivider
    , risePeriod
    , riseRate
    ) where

import Clash.Prelude

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

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 :: Nat).
HiddenClockResetEnable dom =>
SNat n -> Signal dom Bool
riseEvery (KnownNat (Div ps (DomainConfigurationPeriod (KnownConf dom))) =>
SNat (Div ps (DomainConfigurationPeriod (KnownConf dom)))
forall (n :: Nat). 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 :: Nat) (dom :: Domain).
(HiddenClockResetEnable dom, KnownNat ps,
 KnownNat (DomainConfigurationPeriod (KnownConf dom)),
 (1 <=? DomainConfigurationPeriod (KnownConf dom)) ~ 'True) =>
SNat ps -> Signal dom Bool
risePeriod (KnownNat (HzToPeriod rate) => SNat (HzToPeriod rate)
forall (n :: Nat). KnownNat n => SNat n
SNat @(HzToPeriod rate))