+ dobind :: (CoreSyn.CoreBndr, CoreSyn.CoreExpr) -- ^ The bind to process
+ -> TranslatorSession ((Maybe CoreSyn.CoreBndr, Maybe CoreSyn.CoreBndr), ([AST.ConcSm], [CoreSyn.CoreBndr]))
+ -- ^ ((Input state variable, output state variable), (statements, used entities))
+ -- newtype unpacking is just a cast
+ dobind (bndr, (CoreSyn.Cast expr coercion))
+ | hasStateType expr
+ = return ((Just bndr, Nothing), ([], []))
+ -- With simplCore, newtype packing is just a cast
+ dobind (bndr, expr@(CoreSyn.Cast (CoreSyn.Var state) coercion))
+ | hasStateType expr
+ = return ((Nothing, Just state), ([], []))
+ -- Without simplCore, newtype packing uses a data constructor
+ dobind (bndr, (CoreSyn.App (CoreSyn.App (CoreSyn.Var con) (CoreSyn.Type _)) (CoreSyn.Var state)))
+ | isStateCon con
+ = return ((Nothing, Just state), ([], []))
+ -- Anything else is handled by mkConcSm
+ dobind bind = do
+ sms <- mkConcSm bind
+ return ((Nothing, Nothing), sms)
+
+mkStateProcSm ::
+ (CoreSyn.CoreBndr, CoreSyn.CoreBndr) -- ^ The current and new state variables
+ -> AST.ProcSm -- ^ The resulting statement
+mkStateProcSm (old, new) =
+ AST.ProcSm label [clk] [statement]
+ where
+ label = mkVHDLBasicId $ "state"
+ clk = mkVHDLBasicId "clock"
+ rising_edge = AST.NSimple $ mkVHDLBasicId "rising_edge"
+ wform = AST.Wform [AST.WformElem (AST.PrimName $ varToVHDLName new) Nothing]
+ assign = AST.SigAssign (varToVHDLName old) wform
+ rising_edge_clk = AST.PrimFCall $ AST.FCall rising_edge [Nothing AST.:=>: (AST.ADName $ AST.NSimple clk)]
+ statement = AST.IfSm rising_edge_clk [assign] [] Nothing
+