module Lava.Arithmetic where
import Lava
import Lava.Patterns
halfAdd :: (Signal Bool, Signal Bool) -> (Signal Bool, Signal Bool)
halfAdd (a :: Signal Bool
a, b :: Signal Bool
b) = (Signal Bool
sum, Signal Bool
carry)
where
sum :: Signal Bool
sum = (Signal Bool, Signal Bool) -> Signal Bool
xor2 (Signal Bool
a, Signal Bool
b)
carry :: Signal Bool
carry = (Signal Bool, Signal Bool) -> Signal Bool
and2 (Signal Bool
a, Signal Bool
b)
fullAdd :: (Signal Bool, (Signal Bool, Signal Bool))
-> (Signal Bool, Signal Bool)
fullAdd (carryIn :: Signal Bool
carryIn, (a :: Signal Bool
a, b :: Signal Bool
b)) = (Signal Bool
sum, Signal Bool
carryOut)
where
(sum1 :: Signal Bool
sum1, carry1 :: Signal Bool
carry1) = (Signal Bool, Signal Bool) -> (Signal Bool, Signal Bool)
halfAdd (Signal Bool
a, Signal Bool
b)
(sum :: Signal Bool
sum, carry2 :: Signal Bool
carry2) = (Signal Bool, Signal Bool) -> (Signal Bool, Signal Bool)
halfAdd (Signal Bool
carryIn, Signal Bool
sum1)
carryOut :: Signal Bool
carryOut = (Signal Bool, Signal Bool) -> Signal Bool
xor2 (Signal Bool
carry1, Signal Bool
carry2)
bitAdder :: (Signal Bool, [Signal Bool]) -> ([Signal Bool], Signal Bool)
bitAdder = ((Signal Bool, Signal Bool) -> (Signal Bool, Signal Bool))
-> (Signal Bool, [Signal Bool]) -> ([Signal Bool], Signal Bool)
forall b a1 a2. ((b, a1) -> (a2, b)) -> (b, [a1]) -> ([a2], b)
row (Signal Bool, Signal Bool) -> (Signal Bool, Signal Bool)
halfAdd
adder :: (Signal Bool, ([Signal Bool], [Signal Bool]))
-> ([Signal Bool], Signal Bool)
adder (carryIn :: Signal Bool
carryIn, ([], [])) = ([], Signal Bool
carryIn)
adder (carryIn :: Signal Bool
carryIn, (as :: [Signal Bool]
as, [])) = (Signal Bool, [Signal Bool]) -> ([Signal Bool], Signal Bool)
bitAdder (Signal Bool
carryIn, [Signal Bool]
as)
adder (carryIn :: Signal Bool
carryIn, ([], bs :: [Signal Bool]
bs)) = (Signal Bool, [Signal Bool]) -> ([Signal Bool], Signal Bool)
bitAdder (Signal Bool
carryIn, [Signal Bool]
bs)
adder (carryIn :: Signal Bool
carryIn, (a :: Signal Bool
a:as :: [Signal Bool]
as, b :: Signal Bool
b:bs :: [Signal Bool]
bs)) = (Signal Bool
sSignal Bool -> [Signal Bool] -> [Signal Bool]
forall a. a -> [a] -> [a]
:[Signal Bool]
ss, Signal Bool
carryOut)
where
(s :: Signal Bool
s, carry :: Signal Bool
carry) = (Signal Bool, (Signal Bool, Signal Bool))
-> (Signal Bool, Signal Bool)
fullAdd (Signal Bool
carryIn, (Signal Bool
a, Signal Bool
b))
(ss :: [Signal Bool]
ss, carryOut :: Signal Bool
carryOut) = (Signal Bool, ([Signal Bool], [Signal Bool]))
-> ([Signal Bool], Signal Bool)
adder (Signal Bool
carry, ([Signal Bool]
as, [Signal Bool]
bs))
binAdder :: ([Signal Bool], [Signal Bool]) -> [Signal Bool]
binAdder (as :: [Signal Bool]
as, bs :: [Signal Bool]
bs) = [Signal Bool]
sum [Signal Bool] -> [Signal Bool] -> [Signal Bool]
forall a. [a] -> [a] -> [a]
++ [Signal Bool
carryOut]
where
(sum :: [Signal Bool]
sum, carryOut :: Signal Bool
carryOut) = (Signal Bool, ([Signal Bool], [Signal Bool]))
-> ([Signal Bool], Signal Bool)
adder (Signal Bool
low, ([Signal Bool]
as, [Signal Bool]
bs))
bitMulti :: (Signal Bool, [Signal Bool]) -> [Signal Bool]
bitMulti (a :: Signal Bool
a, bs :: [Signal Bool]
bs) = [ (Signal Bool, Signal Bool) -> Signal Bool
and2 (Signal Bool
a, Signal Bool
b) | Signal Bool
b <- [Signal Bool]
bs ]
multi :: ([Signal Bool], [Signal Bool]) -> [Signal Bool]
multi ([], []) = []
multi (as :: [Signal Bool]
as, []) = Int -> Signal Bool -> [Signal Bool]
forall a. Int -> a -> [a]
replicate ([Signal Bool] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Signal Bool]
as) Signal Bool
low
multi ([], bs :: [Signal Bool]
bs) = Int -> Signal Bool -> [Signal Bool]
forall a. Int -> a -> [a]
replicate ([Signal Bool] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Signal Bool]
bs) Signal Bool
low
multi (a :: Signal Bool
a:as :: [Signal Bool]
as, bs :: [Signal Bool]
bs) = Signal Bool
m Signal Bool -> [Signal Bool] -> [Signal Bool]
forall a. a -> [a] -> [a]
: [Signal Bool]
ms
where
(m :: Signal Bool
m:abs :: [Signal Bool]
abs) = (Signal Bool, [Signal Bool]) -> [Signal Bool]
bitMulti (Signal Bool
a, [Signal Bool]
bs)
asbs :: [Signal Bool]
asbs = ([Signal Bool], [Signal Bool]) -> [Signal Bool]
multi ([Signal Bool]
as, [Signal Bool]
bs)
(ms :: [Signal Bool]
ms,_) = (Signal Bool, ([Signal Bool], [Signal Bool]))
-> ([Signal Bool], Signal Bool)
adder (Signal Bool
low, ([Signal Bool]
abs, [Signal Bool]
asbs))
numBreak :: Signal Int -> (Signal Bool, Signal Int)
numBreak num :: Signal Int
num = (Signal Bool
bit, Signal Int
num')
where
digit :: Signal Int
digit = (Signal Int, Signal Int) -> Signal Int
imod (Signal Int
num, 2)
bit :: Signal Bool
bit = Signal Int -> Signal Bool
int2bit Signal Int
digit
num' :: Signal Int
num' = (Signal Int, Signal Int) -> Signal Int
idiv (Signal Int
num, 2)
int2bin :: a -> Signal Int -> [Signal Bool]
int2bin 0 num :: Signal Int
num = []
int2bin n :: a
n num :: Signal Int
num = (Signal Bool
bitSignal Bool -> [Signal Bool] -> [Signal Bool]
forall a. a -> [a] -> [a]
:[Signal Bool]
bits)
where
(bit :: Signal Bool
bit,num' :: Signal Int
num') = Signal Int -> (Signal Bool, Signal Int)
numBreak Signal Int
num
bits :: [Signal Bool]
bits = a -> Signal Int -> [Signal Bool]
int2bin (a
na -> a -> a
forall a. Num a => a -> a -> a
-1) Signal Int
num'
bin2int :: [Signal Bool] -> Signal Int
bin2int [] = 0
bin2int (b :: Signal Bool
b:bs :: [Signal Bool]
bs) = Signal Int
num
where
num' :: Signal Int
num' = [Signal Bool] -> Signal Int
bin2int [Signal Bool]
bs
num :: Signal Int
num = Signal Bool -> Signal Int
bit2int Signal Bool
b Signal Int -> Signal Int -> Signal Int
forall a. Num a => a -> a -> a
+ 2 Signal Int -> Signal Int -> Signal Int
forall a. Num a => a -> a -> a
* Signal Int
num'