module Copilot.Library.Clocks
( clk, clk1, period, phase ) where
import Prelude ( Integral, fromIntegral, ($))
import qualified Prelude as P
import Copilot.Language
data ( Integral a ) => Period a = Period a
data ( Integral a ) => Phase a = Phase a
period :: ( Integral a ) => a -> Period a
period = Period
phase :: ( Integral a ) => a -> Phase a
phase = Phase
clk :: ( Integral a ) => Period a -> Phase a -> Stream Bool
clk ( Period period' ) ( Phase phase' ) = clk'
where clk' = if period' P.< 1 then
badUsage ( "clk: clock period must be 1 or greater" )
else if phase' P.< 0 then
badUsage ( "clk: clock phase must be 0 or greater" )
else if phase' P.>= period' then
badUsage ( "clk: clock phase must be less than period")
else replicate ( fromIntegral phase' ) False
P.++ True : replicate
( fromIntegral
$ period' P.- phase' P.- 1 ) False
++ clk'
clk1 :: ( Integral a, Typed a )
=> Period a -> Phase a -> Stream Bool
clk1 ( Period period' ) ( Phase phase' ) =
if period' P.< 1 then
badUsage ( "clk1: clock period must be 1 or greater" )
else if phase' P.< 0 then
badUsage ( "clk1: clock phase must be 0 or greater" )
else if phase' P.>= period' then
badUsage ( "clk1: clock phase must be less than period")
else
let counter = [ P.fromInteger 0 ]
++ mux ( counter /= ( constant $
period' P.- 1 ) )
( counter P.+ 1 )
( 0 )
in counter == fromIntegral phase'