Wired-0.1: Examples/UsingLava.hs
import Lava
import Libs.Simple130nm.Lava
import qualified Lava2000 as L
import Control.Monad.Trans
import Data.Logical.Let
-- Only used in circLoop2.
circ1 :: (Signal,Signal) -> Lava Simple130nm Signal
circ1 = and2 ->- inv
circ1' (a,b) = do
c <- and2 (a,b)
inv c
-- Same as circ1.
circ2 = halfAdd ->- and2 ->- inv
circLoop = mdo
a <- label "a" =<< and2 (b,b)
b <- label "b" =<< inv c
c <- label "c" =<< and2 (b,a)
return b
-- Labels are not needed for definition.
circLoop2 = runLetT $ do
b <- free
c <- free
a <- lift $ label "a" =<< and2 (val b, val b)
b' <- lift $ label "b" =<< inv (val c)
c' <- lift $ label "c" =<< and2 (val b, a)
b === b'
c === c'
return b'
-- Alternative definition using logical variables
circInput :: Signal -> Lava Simple130nm Signal
circInput a = do
b <- input "b"
and2 (a,b)
test1 = L.simulateSeq (toLava2000 circ2) L.domain
-- Simulation using Lava2000.
test2 = simulateSeq circ2 [(0,0),(1,1)]
-- Simulation in Lava (uses Lava2000 internally).
test3 = verify circ2
-- Check that output is always high.
test4 = fst $ depth $ circ1 (low,low)
-- Find logcial depth of circ1.
test5 = fst $ depth circLoop
-- Error because of combinational loop.
test6 = lookupTag "b" $ fanout circLoop
-- Find the fanout at node "b". It is perfectly fine to have multiple labels
-- on the same node, and even to use the same label on multiple places (try).
test7 = lookupTag "b" $ fanout circLoop2
-- Just to test
test8 = size circLoop
-- Find number of gates in circLoop.
test9 = simulate circInput 0
-- Inputs can be defined, but they cause error in simulation.