{-# LANGUAGE NoImplicitPrelude #-}
module Copilot.Library.Clocks
( clk, clk1, period, phase ) where
import Prelude ()
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 :: a -> Period a
period = a -> Period a
forall a. a -> Period a
Period
phase :: ( Integral a ) => a -> Phase a
phase :: a -> Phase a
phase = a -> Phase a
forall a. a -> Phase a
Phase
clk :: ( Integral a ) =>
Period a
-> Phase a
-> Stream Bool
clk :: Period a -> Phase a -> Stream Bool
clk ( Period a
period' ) ( Phase a
phase' ) = Stream Bool
clk'
where clk' :: Stream Bool
clk' = if a
period' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.< a
1 then
String -> Stream Bool
forall a. String -> a
badUsage ( String
"clk: clock period must be 1 or greater" )
else if a
phase' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.< a
0 then
String -> Stream Bool
forall a. String -> a
badUsage ( String
"clk: clock phase must be 0 or greater" )
else if a
phase' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.>= a
period' then
String -> Stream Bool
forall a. String -> a
badUsage ( String
"clk: clock phase must be less than period")
else Int -> Bool -> [Bool]
forall a. Int -> a -> [a]
replicate ( a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
phase' ) Bool
False
[Bool] -> [Bool] -> [Bool]
forall a. [a] -> [a] -> [a]
P.++ Bool
True Bool -> [Bool] -> [Bool]
forall a. a -> [a] -> [a]
: Int -> Bool -> [Bool]
forall a. Int -> a -> [a]
replicate
( a -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral
(a -> Int) -> a -> Int
forall a b. (a -> b) -> a -> b
$ a
period' a -> a -> a
forall a. Num a => a -> a -> a
P.- a
phase' a -> a -> a
forall a. Num a => a -> a -> a
P.- a
1 ) Bool
False
[Bool] -> Stream Bool -> Stream Bool
forall a. Typed a => [a] -> Stream a -> Stream a
++ Stream Bool
clk'
clk1 :: ( Integral a, Typed a ) =>
Period a
-> Phase a
-> Stream Bool
clk1 :: Period a -> Phase a -> Stream Bool
clk1 ( Period a
period' ) ( Phase a
phase' ) =
if a
period' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.< a
1 then
String -> Stream Bool
forall a. String -> a
badUsage ( String
"clk1: clock period must be 1 or greater" )
else if a
phase' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.< a
0 then
String -> Stream Bool
forall a. String -> a
badUsage ( String
"clk1: clock phase must be 0 or greater" )
else if a
phase' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.>= a
period' then
String -> Stream Bool
forall a. String -> a
badUsage ( String
"clk1: clock phase must be less than period")
else
let counter :: Stream a
counter = [ Integer -> a
forall a. Num a => Integer -> a
P.fromInteger Integer
0 ]
[a] -> Stream a -> Stream a
forall a. Typed a => [a] -> Stream a -> Stream a
++ Stream Bool -> Stream a -> Stream a -> Stream a
forall a.
Typed a =>
Stream Bool -> Stream a -> Stream a -> Stream a
mux ( Stream a
counter Stream a -> Stream a -> Stream Bool
forall a. (Eq a, Typed a) => Stream a -> Stream a -> Stream Bool
/= ( a -> Stream a
forall a. Typed a => a -> Stream a
constant (a -> Stream a) -> a -> Stream a
forall a b. (a -> b) -> a -> b
$
a
period' a -> a -> a
forall a. Num a => a -> a -> a
P.- a
1 ) )
( Stream a
counter Stream a -> Stream a -> Stream a
forall a. Num a => a -> a -> a
P.+ Stream a
1 )
( Stream a
0 )
in Stream a
counter Stream a -> Stream a -> Stream Bool
forall a. (Eq a, Typed a) => Stream a -> Stream a -> Stream Bool
== a -> Stream a
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
phase'