X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=c%CE%BBash%2FCLasH%2FVHDL%2FGenerate.hs;h=5386e7e61b698a0681830ffc9b4b14c2c9c1e67f;hb=d947c778e6e6e95e896cfc6926a4fdf12f16806d;hp=4de6b400172bf15bdcb439b6a2df9b66cb6b04cc;hpb=fda239f0ae8fc6a2250e6719c3f564c9b2390c4a;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git diff --git "a/c\316\273ash/CLasH/VHDL/Generate.hs" "b/c\316\273ash/CLasH/VHDL/Generate.hs" index 4de6b40..5386e7e 100644 --- "a/c\316\273ash/CLasH/VHDL/Generate.hs" +++ "b/c\316\273ash/CLasH/VHDL/Generate.hs" @@ -28,7 +28,7 @@ import CLasH.Translator.TranslatorTypes import CLasH.VHDL.Constants import CLasH.VHDL.VHDLTypes import CLasH.VHDL.VHDLTools -import qualified CLasH.Utils as Utils +import CLasH.Utils as Utils import CLasH.Utils.Core.CoreTools import CLasH.Utils.Pretty import qualified CLasH.Normalize as Normalize @@ -46,10 +46,12 @@ getEntity fname = Utils.makeCached fname tsEntities $ do expr <- Normalize.getNormalized fname -- Strip off lambda's, these will be arguments let (args, letexpr) = CoreSyn.collectBinders expr - args' <- mapM mkMap args + -- Generate ports for all non-state types + args' <- catMaybesM $ mapM mkMap args -- There must be a let at top level let (CoreSyn.Let binds (CoreSyn.Var res)) = letexpr - res' <- mkMap res + -- TODO: Handle Nothing + Just res' <- mkMap res let vhdl_id = mkVHDLBasicId $ varToString fname ++ "_" ++ varToStringUniq fname let ent_decl = createEntityAST vhdl_id args' res' let signature = Entity vhdl_id args' res' ent_decl @@ -58,7 +60,7 @@ getEntity fname = Utils.makeCached fname tsEntities $ do mkMap :: --[(SignalId, SignalInfo)] CoreSyn.CoreBndr - -> TranslatorSession Port + -> TranslatorSession (Maybe Port) mkMap = (\bndr -> let --info = Maybe.fromMaybe @@ -69,8 +71,10 @@ getEntity fname = Utils.makeCached fname tsEntities $ do ty = Var.varType bndr error_msg = "\nVHDL.createEntity.mkMap: Can not create entity: " ++ pprString fname ++ "\nbecause no type can be created for port: " ++ pprString bndr in do - type_mark <- MonadState.lift tsType $ vhdl_ty error_msg ty - return (id, type_mark) + type_mark_maybe <- MonadState.lift tsType $ vhdl_ty error_msg ty + case type_mark_maybe of + Just type_mark -> return $ Just (id, type_mark) + Nothing -> return Nothing ) -- | Create the VHDL AST for an entity @@ -156,10 +160,14 @@ mkConcSm (bndr, app@(CoreSyn.App _ _))= do -- A single alt case must be a selector. This means thee scrutinee is a simple -- variable, the alternative is a dataalt with a single non-wild binder that -- is also returned. -mkConcSm (bndr, expr@(CoreSyn.Case (CoreSyn.Var scrut) b ty [alt])) = +mkConcSm (bndr, expr@(CoreSyn.Case (CoreSyn.Var scrut) b ty [alt])) + -- Don't generate VHDL for substate extraction + | hasStateType bndr = return ([], []) + | otherwise = case alt of (CoreSyn.DataAlt dc, bndrs, (CoreSyn.Var sel_bndr)) -> do - case List.elemIndex sel_bndr bndrs of + bndrs' <- Monad.filterM hasNonEmptyType bndrs + case List.elemIndex sel_bndr bndrs' of Just i -> do labels <- MonadState.lift tsType $ getFieldLabels (Id.idType scrut) let label = labels!!i @@ -192,11 +200,24 @@ mkConcSm (bndr, expr) = error $ "\nVHDL.mkConcSM: Unsupported binding in let exp -- | A function to wrap a builder-like function that expects its arguments to -- be expressions. genExprArgs wrap dst func args = do - args' <- eitherCoreOrExprArgs args + args' <- argsToVHDLExprs args wrap dst func args' -eitherCoreOrExprArgs :: [Either CoreSyn.CoreExpr AST.Expr] -> TranslatorSession [AST.Expr] -eitherCoreOrExprArgs args = mapM (Either.either ((MonadState.lift tsType) . varToVHDLExpr . exprToVar) return) args +-- | Turn the all lefts into VHDL Expressions. +argsToVHDLExprs :: [Either CoreSyn.CoreExpr AST.Expr] -> TranslatorSession [AST.Expr] +argsToVHDLExprs = catMaybesM . (mapM argToVHDLExpr) + +argToVHDLExpr :: Either CoreSyn.CoreExpr AST.Expr -> TranslatorSession (Maybe AST.Expr) +argToVHDLExpr (Left expr) = MonadState.lift tsType $ do + let errmsg = "Generate.argToVHDLExpr: Using non-representable type? Should not happen!" + ty_maybe <- vhdl_ty errmsg expr + case ty_maybe of + Just _ -> do + vhdl_expr <- varToVHDLExpr $ exprToVar expr + return $ Just vhdl_expr + Nothing -> return $ Nothing + +argToVHDLExpr (Right expr) = return $ Just expr -- A function to wrap a builder-like function that generates no component -- instantiations @@ -485,7 +506,8 @@ genFold'' len left (Left res) f [folded_f, start, vec] = do -- temporary vector let tmp_ty = Type.mkAppTy nvec (Var.varType start) let error_msg = "\nGenerate.genFold': Can not construct temp vector for element type: " ++ pprString tmp_ty - tmp_vhdl_ty <- MonadState.lift tsType $ vhdl_ty error_msg tmp_ty + -- TODO: Handle Nothing + Just tmp_vhdl_ty <- MonadState.lift tsType $ vhdl_ty error_msg tmp_ty -- Setup the generate scheme let gen_label = mkVHDLExtId ("foldlVector" ++ (varToString vec)) let block_label = mkVHDLExtId ("foldlVector" ++ (varToString res)) @@ -687,7 +709,8 @@ genIterateOrGenerate'' len iter (Left res) f [app_f, start] = do -- -- temporary vector let tmp_ty = Var.varType res let error_msg = "\nGenerate.genFold': Can not construct temp vector for element type: " ++ pprString tmp_ty - tmp_vhdl_ty <- MonadState.lift tsType $ vhdl_ty error_msg tmp_ty + -- TODO: Handle Nothing + Just tmp_vhdl_ty <- MonadState.lift tsType $ vhdl_ty error_msg tmp_ty -- Setup the generate scheme let gen_label = mkVHDLExtId ("iterateVector" ++ (varToString start)) let block_label = mkVHDLExtId ("iterateVector" ++ (varToString res)) @@ -764,12 +787,12 @@ genApplication dst f args = do -- Local binder that references a top level binding. Generate a -- component instantiation. signature <- getEntity f - args' <- eitherCoreOrExprArgs args + args' <- argsToVHDLExprs args let entity_id = ent_id signature -- TODO: Using show here isn't really pretty, but we'll need some -- unique-ish value... let label = "comp_ins_" ++ (either show prettyShow) dst - let portmaps = mkAssocElems args' ((either varToVHDLName id) dst) signature + portmaps <- mkAssocElems args' ((either varToVHDLName id) dst) signature return ([mkComponentInst label entity_id portmaps], [f]) False -> do -- Not a top level binder, so this must be a local variable reference. @@ -785,7 +808,7 @@ genApplication dst f args = do Left bndr -> do -- We have the bndr, so we can get at the type labels <- MonadState.lift tsType $ getFieldLabels (Var.varType bndr) - args' <- eitherCoreOrExprArgs args + args' <- argsToVHDLExprs args return $ (zipWith mkassign labels $ args', []) where mkassign :: AST.VHDLId -> AST.Expr -> AST.ConcSm @@ -848,7 +871,8 @@ genApplication dst f args = do vectorFunId :: Type.Type -> String -> TypeSession AST.VHDLId vectorFunId el_ty fname = do let error_msg = "\nGenerate.vectorFunId: Can not construct vector function for element: " ++ pprString el_ty - elemTM <- vhdl_ty error_msg el_ty + -- TODO: Handle the Nothing case? + Just elemTM <- vhdl_ty error_msg el_ty -- TODO: This should not be duplicated from mk_vector_ty. Probably but it in -- the VHDLState or something. let vectorTM = mkVHDLExtId $ "vector_" ++ (AST.fromVHDLId elemTM)