package SVA2 where import List orM :: Maybe Bool -> Maybe Bool -> Maybe Bool orM Nothing Nothing = Nothing orM Nothing y = y orM x Nothing = x orM (Just x) (Just y) = Just (x || y) andM :: Maybe Bool -> Maybe Bool -> Maybe Bool andM (Just x) (Just y) = Just (x && y) andM x y = Nothing notM :: Maybe Bool -> Maybe Bool notM Nothing = Nothing notM (Just x) = Just (not x) orLeft :: Maybe Bool -> Maybe Bool -> Maybe Bool orLeft x y = case x of Nothing -> y Just b1 -> case y of Nothing -> Just b1 Just b2 -> Just (b1 || b2) andLeft :: Maybe Bool -> Maybe Bool -> Maybe Bool andLeft x y = case x of Nothing -> y Just b1 -> case y of Nothing -> Just b1 Just b2 -> Just (b1 && b2) interface Sequence = running :: Bool advance :: ActionValue (Maybe Bool) mkSeqVoid :: (IsModule m c) => m Sequence mkSeqVoid = module interface running = False advance = return (Just False) mkSeqTrue :: (IsModule m c) => m Sequence mkSeqTrue = module interface running = False advance = return (Just True) mkSeqExpr :: (IsModule m c) => Bool -> m Sequence mkSeqExpr dynbool = module interface running = False advance = do return (Just dynbool) mkSeqAsgn :: (IsModule m c) => Action -> m Sequence mkSeqAsgn dynaction = module interface advance = do dynaction return (Just True) running = False mkSeqConcat :: (IsModule m c) => Sequence -> Sequence -> m Sequence mkSeqConcat s1 s2 = module start <- mkReg False interface running = s1.running || s2.running || start advance = do (s, res) <- if s1.running || (not s1.running && not s2.running) && not start then do r <- s1.advance let b = case r of Nothing -> False Just z -> z return (b, Nothing) else do r2 <- s2.advance return (False, r2) start := s return res mkSeqFuse :: (IsModule m c) => Sequence -> Sequence -> m Sequence mkSeqFuse s1 s2 = module interface running = s1.running || s2.running advance = do start <- if s1.running || (not s1.running && not s2.running) then do r <- s1.advance let b = case r of Nothing -> False Just z -> z return b else return False res <- if s2.running || start then do r <- s2.advance return r else return Nothing return res interface SequenceList = anyRunning :: Bool startNew :: ActionValue (Maybe Bool) advanceRunning :: ActionValue (List (Maybe Bool)) mkSequenceList :: (IsModule m c) => List Sequence -> m SequenceList mkSequenceList ss = module let doRunning :: Sequence -> Bool doRunning x = x.running doAdvance :: Sequence -> ActionValue (Maybe Bool) doAdvance x = if x.running then x.advance else return Nothing getFree :: List Sequence -> ActionValue (Maybe Bool) getFree Nil = return Nothing getFree (Cons x xs) = if not x.running then x.advance else getFree xs interface anyRunning = or (map doRunning ss) startNew = getFree ss advanceRunning = mapM doAdvance ss mkSeqConcatMany :: (IsModule m c) => Sequence -> List Sequence -> m Sequence mkSeqConcatMany s1 s2 = module start <- mkReg False s2s <- mkSequenceList s2 interface running = s1.running || s2s.anyRunning advance = do s <- if s1.running || (not s2s.anyRunning) then do r1 <- s1.advance return $ case r1 of Nothing -> False Just b -> b else return False r <- if start then s2s.startNew else return Nothing start := s rs <- s2s.advanceRunning return (foldl orLeft r rs) mkSeqFuseMany :: (IsModule m c) => Sequence -> List Sequence -> m Sequence mkSeqFuseMany s1 s2 = module s2s <- mkSequenceList s2 interface running = s1.running || s2s.anyRunning advance = do start <- if s1.running || (not s2s.anyRunning) then do r1 <- s1.advance return $ case r1 of Nothing -> False Just b -> b else return False r <- if start then s2s.startNew else return Nothing rs <- s2s.advanceRunning return (foldl orLeft r rs) mkSeqOr :: (IsModule m c) => Sequence -> Sequence -> m Sequence mkSeqOr s1 s2 = module interface running = s1.running || s2.running advance = do res_l <- if (not s1.running && not s2.running) || s1.running then s1.advance else return Nothing res_r <- if (not s1.running && not s2.running) || s2.running then s2.advance else return Nothing return (orM res_l res_r) mkSeqIntersect :: (IsModule m c) => Sequence -> Sequence -> m Sequence mkSeqIntersect s1 s2 = module interface running = s1.running && s2.running advance = do r1 <- s1.advance r2 <- s2.advance return (andM r1 r2) mkSeqFirstMatch :: (IsModule m c) => Sequence -> m Sequence mkSeqFirstMatch seq = module run <- mkReg False interface running = run advance = do r <- seq.advance let b = case r of Nothing -> True Just z -> not z run := seq.running && b return r mkSeqNull :: (IsModule m c) => Sequence -> m Sequence mkSeqNull s = module interface running = False advance = return (Just True) mkSeqUnbound :: (IsModule m c) => Sequence -> m Sequence mkSeqUnbound seq = module run <- mkReg False interface running = run advance = do run := True r <- seq.advance return r interface Property = running :: Bool advance :: ActionValue (Maybe Bool) mkPropSeq :: (IsModule m c) => Sequence -> m Property mkPropSeq seq = module interface running = seq.running advance = do r <- seq.advance return r mkPropNot :: (IsModule m c) => Property -> m Property mkPropNot prop = module interface running = prop.running advance = do r <- prop.advance return (notM r) mkPropOr :: (IsModule m c) => Property -> Property -> m Property mkPropOr p1 p2 = module run_1 <- mkReg False run_2 <- mkReg False interface running = run_1 || run_2 advance = do res_l <- if (not run_1 && not run_2) || run_1 then -- p1 is running, or we're starting over p1.advance else return Nothing res_r <- if (not run_1 && not run_2) || run_2 then -- p2 is running, or we're starting over p2.advance else return Nothing let res = orM res_l res_r run_1 := p1.running && not (isJust res_l) run_2 := p2.running && not (isJust res_r) return res mkPropAnd :: (IsModule m c) => Property -> Property -> m Property mkPropAnd p1 p2 = module run_1 <- mkReg False run_2 <- mkReg False interface running = run_1 && run_2 advance = do r1 <- p1.advance run_1 := p1.running r2 <- p2.advance run_2 := p2.running return (andM r1 r2) interface PropertyList = anyRunning :: Bool startNew :: ActionValue (Maybe Bool) advanceRunning :: ActionValue (List (Maybe Bool)) mkPropertyList :: (IsModule m c) => List Property -> m PropertyList mkPropertyList ps = module let doRunning :: Property -> Bool doRunning x = x.running doAdvance :: Property -> ActionValue (Maybe Bool) doAdvance x = if x.running then x.advance else return Nothing getFree :: List Property -> ActionValue (Maybe Bool) getFree Nil = return Nothing getFree (Cons x xs) = if not x.running then x.advance else getFree xs interface anyRunning = or (map doRunning ps) startNew = getFree ps advanceRunning = mapM doAdvance ps mkPropImplies :: (IsModule m c) => List Sequence -> List Property -> m Property mkPropImplies s p = module let ss <- mkSequenceList s ps <- mkPropertyList p interface running = ss.anyRunning advance = do starts <- ss.advanceRunning sNew <- ss.startNew let start = case foldl orLeft sNew starts of Nothing -> False Just b -> b rNew <- if start then ps.startNew else return Nothing rs <- ps.advanceRunning return (foldl orLeft rNew rs) interface Assertion = advance :: ActionValue Bool --False if assertion FAILS mkAssert :: (IsModule m c) => Property -> Action -> Action -> m Assertion mkAssert p pass fail = module interface advance = do r <- p.advance res <- case r of Nothing -> return True Just b -> if b then do pass return True else do fail return False return res mkAssertAlways :: (IsModule m c) => List Property -> Action -> Action -> m Assertion mkAssertAlways p pass fail = module let doAction x = case x of Nothing -> noAction Just b -> if b then pass else fail getRes x y = case x of Nothing -> y ps <- mkPropertyList p interface advance = do rNew <- ps.startNew rs <- ps.advanceRunning mapM doAction (rNew :> rs) return $ case foldl andLeft rNew rs of Nothing -> True Just b -> b mkTest :: Module (Empty) mkTest = module x :: Reg (Int 3) <- mkReg 1 y :: Reg (Int 3) <- mkReg 0 a :: Reg Bool <- mkReg True b :: Reg Bool <- mkReg True c :: Reg Bool <- mkReg True localvar :: Reg (Int 32) <- mkReg 0 res1 :: Reg Bool <- mkReg True res2 :: Reg Bool <- mkReg True let isOdd :: (Bitwise a, Eq a, Arith a) => a -> Bool isOdd p = if (p & 1) == 1 then True else False alwaysTrue :: a -> Bool alwaysTrue p = True isEven :: (Bitwise a, Eq a, Arith a) => a -> Bool isEven p = not (isOdd p) actFail :: Action actFail = action { $display "FAIL"; $finish; } actPass :: Action actPass = action { $display "PASS"; $finish; } asgnLocal :: Int 32 -> Action asgnLocal pm = action { localvar := pm } assertion_0_24_gen :: Module Property assertion_0_24_gen = module assertion_0_1 <- mkSeqExpr (x /= y) assertion_0_2 <- mkSeqTrue assertion_0_3 <- mkSeqNull assertion_0_2 assertion_0_4 <- mkSeqConcat assertion_0_2 assertion_0_2 assertion_0_40 <- mkSeqConcat assertion_0_2 assertion_0_2 assertion_0_41 <- mkSeqConcat assertion_0_2 assertion_0_2 assertion_0_42 <- mkSeqConcat assertion_0_2 assertion_0_2 assertion_0_43 <- mkSeqConcat assertion_0_2 assertion_0_2 assertion_0_44 <- mkSeqConcat assertion_0_2 assertion_0_2 assertion_0_45 <- mkSeqConcat assertion_0_2 assertion_0_2 assertion_0_46 <- mkSeqConcat assertion_0_2 assertion_0_2 assertion_0_47 <- mkSeqConcat assertion_0_2 assertion_0_2 assertion_0_5 <- mkSeqConcat assertion_0_2 assertion_0_41 assertion_0_50 <- mkSeqConcat assertion_0_2 assertion_0_4 assertion_0_51 <- mkSeqConcat assertion_0_2 assertion_0_42 assertion_0_52 <- mkSeqConcat assertion_0_2 assertion_0_43 assertion_0_53 <- mkSeqConcat assertion_0_2 assertion_0_44 assertion_0_54 <- mkSeqConcat assertion_0_2 assertion_0_45 assertion_0_55 <- mkSeqConcat assertion_0_2 assertion_0_46 assertion_0_56 <- mkSeqConcat assertion_0_2 assertion_0_47 assertion_0_6 <- mkSeqConcat assertion_0_2 assertion_0_52 assertion_0_60 <- mkSeqConcat assertion_0_2 assertion_0_5 assertion_0_61 <- mkSeqConcat assertion_0_2 assertion_0_53 assertion_0_62 <- mkSeqConcat assertion_0_2 assertion_0_54 assertion_0_63 <- mkSeqConcat assertion_0_2 assertion_0_55 assertion_0_64 <- mkSeqConcat assertion_0_2 assertion_0_56 assertion_0_7 <- mkSeqConcat assertion_0_2 assertion_0_61 assertion_0_70 <- mkSeqConcat assertion_0_2 assertion_0_6 assertion_0_71 <- mkSeqConcat assertion_0_2 assertion_0_62 assertion_0_72 <- mkSeqConcat assertion_0_2 assertion_0_63 assertion_0_73 <- mkSeqConcat assertion_0_2 assertion_0_64 assertion_0_8 <- mkSeqConcat assertion_0_2 assertion_0_71 assertion_0_80 <- mkSeqConcat assertion_0_2 assertion_0_7 assertion_0_81 <- mkSeqConcat assertion_0_2 assertion_0_72 assertion_0_82 <- mkSeqConcat assertion_0_2 assertion_0_73 assertion_0_9 <- mkSeqConcat assertion_0_2 assertion_0_81 assertion_0_90 <- mkSeqConcat assertion_0_2 assertion_0_8 assertion_0_91 <- mkSeqConcat assertion_0_2 assertion_0_82 assertion_0_10 <- mkSeqConcat assertion_0_2 assertion_0_91 assertion_0_100 <- mkSeqConcat assertion_0_2 assertion_0_9 assertion_0_11 <- mkSeqConcat assertion_0_2 assertion_0_10 assertion_0_12 <- mkSeqOr assertion_0_100 assertion_0_11 assertion_0_13 <- mkSeqOr assertion_0_90 assertion_0_12 assertion_0_14 <- mkSeqOr assertion_0_80 assertion_0_13 assertion_0_15 <- mkSeqOr assertion_0_70 assertion_0_14 assertion_0_16 <- mkSeqOr assertion_0_60 assertion_0_15 assertion_0_17 <- mkSeqOr assertion_0_50 assertion_0_16 assertion_0_18 <- mkSeqOr assertion_0_40 assertion_0_17 assertion_0_19 <- mkSeqOr assertion_0_2 assertion_0_18 assertion_0_20 <- mkSeqOr assertion_0_3 assertion_0_19 assertion_0_21 <- mkSeqExpr (x /= 3) assertion_0_22 <- mkSeqConcat assertion_0_20 assertion_0_21 assertion_0_23 <- mkSeqConcat assertion_0_1 assertion_0_22 mkPropSeq assertion_0_23 assertion_0_0_gen :: Module Sequence assertion_0_0_gen = module mkSeqExpr (x < 0) assertion_0_1_gen :: Module Property assertion_0_1_gen = module assertion_0_0 <- mkSeqExpr (x /= 0) assertion_0_1 <- mkSeqTrue assertion_0_2 <- mkSeqConcat assertion_0_1 assertion_0_0 mkPropSeq assertion_0_2 assertion_0_0_lst <- replicateM 1 assertion_0_0_gen assertion_0_1_lst <- replicateM 2 assertion_0_1_gen --assertion_0_24_lst <- replicateM 6 assertion_0_24_gen assertion_0_25 <- mkPropImplies assertion_0_0_lst assertion_0_1_lst assertion_0 :: Assertion <- mkAssert assertion_0_25 ($display "PASSED!") $finish --($display "FAILED!") interface rules when True ==> action x := x + 1 y := y + 1 a := b b := c c := a r1 :: Bool <- assertion_0.advance res1 := r1