X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=c%CE%BBash%2FCLasH%2FVHDL%2FGenerate.hs;h=5698ef89a6efe29503b4c263b524c288a46f0016;hb=f0c06cad4df4d07d2d8542e6454cffb06f620719;hp=591e9408f6bbe742b0127218c3aa92fa497b2a5f;hpb=bf9f8e9e9cfce93ae1e35cf524b371beb34f5010;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 591e940..5698ef8 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,20 +46,21 @@ 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 AST.EntityDec entity_id _ = ent_decl' - let signature = Entity entity_id args' res' ent_decl' + let ent_decl = createEntityAST vhdl_id args' res' + let signature = Entity vhdl_id args' res' ent_decl return signature where mkMap :: --[(SignalId, SignalInfo)] CoreSyn.CoreBndr - -> TranslatorSession Port + -> TranslatorSession (Maybe Port) mkMap = (\bndr -> let --info = Maybe.fromMaybe @@ -70,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 @@ -157,7 +160,10 @@ 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 @@ -314,12 +320,17 @@ genFromInteger' (Left res) f lits = do { ; (tycon, args) = Type.splitTyConApp ty ; name = Name.getOccString (TyCon.tyConName tycon) } ; - ; len <- case name of - "SizedInt" -> MonadState.lift tsType $ tfp_to_int (sized_int_len_ty ty) - "SizedWord" -> MonadState.lift tsType $ tfp_to_int (sized_word_len_ty ty) - ; let fname = case name of "SizedInt" -> toSignedId ; "SizedWord" -> toUnsignedId - ; return $ AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLBasicId fname)) - [Nothing AST.:=>: AST.ADExpr (AST.PrimLit (show (last lits))), Nothing AST.:=>: AST.ADExpr( AST.PrimLit (show len))] + ; case name of + "RangedWord" -> return $ AST.PrimLit (show (last lits)) + otherwise -> do { + ; len <- case name of + "SizedInt" -> MonadState.lift tsType $ tfp_to_int (sized_int_len_ty ty) + "SizedWord" -> MonadState.lift tsType $ tfp_to_int (sized_word_len_ty ty) + "RangedWord" -> MonadState.lift tsType $ tfp_to_int (ranged_word_bound_ty ty) + ; let fname = case name of "SizedInt" -> toSignedId ; "SizedWord" -> toUnsignedId + ; return $ AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLBasicId fname)) + [Nothing AST.:=>: AST.ADExpr (AST.PrimLit (show (last lits))), Nothing AST.:=>: AST.ADExpr( AST.PrimLit (show len))] + } } genFromInteger' (Right name) _ _ = error $ "\nGenerate.genFromInteger': Cannot generate builtin function call assigned to a VHDLName: " ++ show name @@ -481,7 +492,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)) @@ -683,7 +695,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)) @@ -774,7 +787,7 @@ genApplication dst f args = do -- assignment here. f' <- MonadState.lift tsType $ varToVHDLExpr f return $ ([mkUncondAssign dst f'], []) - True -> + True | not stateful -> case Var.idDetails f of IdInfo.DataConWorkId dc -> case dst of -- It's a datacon. Create a record from its arguments. @@ -824,6 +837,16 @@ genApplication dst f args = do error $ "\nGenerate.genApplication(ClassOpId): Incorrect number of arguments to builtin function: " ++ pprString f ++ " Args: " ++ show args Nothing -> error $ "\nGenerate.genApplication(ClassOpId): Using function from another module that is not a known builtin: " ++ pprString f details -> error $ "\nGenerate.genApplication: Calling unsupported function " ++ pprString f ++ " with GlobalIdDetails " ++ pprString details + -- If we can't generate a component instantiation, and the destination is + -- a state type, don't generate anything. + _ -> return ([], []) + where + -- Is our destination a state value? + stateful = case dst of + -- When our destination is a VHDL name, it won't have had a state type + Right _ -> False + -- Otherwise check its type + Left bndr -> hasStateType bndr ----------------------------------------------------------------------------- -- Functions to generate functions dealing with vectors. @@ -834,7 +857,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) @@ -862,7 +886,8 @@ genUnconsVectorFuns elemTM vectorTM = , (replaceId, (AST.SubProgBody replaceSpec [AST.SPVD replaceVar] [replaceExpr,replaceRet],[])) , (lastId, (AST.SubProgBody lastSpec [] [lastExpr],[])) , (initId, (AST.SubProgBody initSpec [AST.SPVD initVar] [initExpr, initRet],[])) - , (takeId, (AST.SubProgBody takeSpec [AST.SPVD takeVar] [takeExpr, takeRet],[])) + , (minimumId, (AST.SubProgBody minimumSpec [] [minimumExpr],[])) + , (takeId, (AST.SubProgBody takeSpec [AST.SPVD takeVar] [takeExpr, takeRet],[minimumId])) , (dropId, (AST.SubProgBody dropSpec [AST.SPVD dropVar] [dropExpr, dropRet],[])) , (plusgtId, (AST.SubProgBody plusgtSpec [AST.SPVD plusgtVar] [plusgtExpr, plusgtRet],[])) , (emptyId, (AST.SubProgBody emptySpec [AST.SPCD emptyVar] [emptyExpr],[])) @@ -885,12 +910,14 @@ genUnconsVectorFuns elemTM vectorTM = vec1Par = AST.unsafeVHDLBasicId "vec1" vec2Par = AST.unsafeVHDLBasicId "vec2" nPar = AST.unsafeVHDLBasicId "n" + leftPar = AST.unsafeVHDLBasicId "nLeft" + rightPar = AST.unsafeVHDLBasicId "nRight" iId = AST.unsafeVHDLBasicId "i" iPar = iId aPar = AST.unsafeVHDLBasicId "a" fPar = AST.unsafeVHDLBasicId "f" sPar = AST.unsafeVHDLBasicId "s" - resId = AST.unsafeVHDLBasicId "res" + resId = AST.unsafeVHDLBasicId "res" exSpec = AST.Function (mkVHDLExtId exId) [AST.IfaceVarDec vecPar vectorTM, AST.IfaceVarDec ixPar naturalTM] elemTM exExpr = AST.ReturnSm (Just $ AST.PrimName $ AST.NIndexed @@ -948,21 +975,32 @@ genUnconsVectorFuns elemTM vectorTM = AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-: AST.PrimLit "2")) initRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId) + minimumSpec = AST.Function (mkVHDLExtId minimumId) [AST.IfaceVarDec leftPar naturalTM, + AST.IfaceVarDec rightPar naturalTM ] naturalTM + minimumExpr = AST.IfSm ((AST.PrimName $ AST.NSimple leftPar) AST.:<: (AST.PrimName $ AST.NSimple rightPar)) + [AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple leftPar)] + [] + (Just $ AST.Else [minimumExprRet]) + where minimumExprRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple rightPar) takeSpec = AST.Function (mkVHDLExtId takeId) [AST.IfaceVarDec nPar naturalTM, AST.IfaceVarDec vecPar vectorTM ] vectorTM - -- variable res : fsvec_x (0 to n-1); + -- variable res : fsvec_x (0 to (minimum (n,vec'length))-1); + minLength = AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId minimumId)) + [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple nPar) + ,Nothing AST.:=>: AST.ADExpr (AST.PrimName (AST.NAttribute $ + AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing))] takeVar = AST.VarDec resId (AST.SubtypeIn vectorTM (Just $ AST.ConstraintIndex $ AST.IndexConstraint [AST.ToRange (AST.PrimLit "0") - ((AST.PrimName (AST.NSimple nPar)) AST.:-: + (minLength AST.:-: (AST.PrimLit "1")) ])) Nothing -- res AST.:= vec(0 to n-1) takeExpr = AST.NSimple resId AST.:= - (vecSlice (AST.PrimLit "1") - (AST.PrimName (AST.NSimple $ nPar) AST.:-: AST.PrimLit "1")) + (vecSlice (AST.PrimLit "0") + (minLength AST.:-: AST.PrimLit "1")) takeRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId) dropSpec = AST.Function (mkVHDLExtId dropId) [AST.IfaceVarDec nPar naturalTM, AST.IfaceVarDec vecPar vectorTM ] vectorTM @@ -1231,7 +1269,7 @@ type NameTable = Map.Map String (Int, BuiltinBuilder ) -- builder function. globalNameTable :: NameTable globalNameTable = Map.fromList - [ (exId , (2, genFCall False ) ) + [ (exId , (2, genFCall True ) ) , (replaceId , (3, genFCall False ) ) , (headId , (1, genFCall True ) ) , (lastId , (1, genFCall True ) ) @@ -1278,4 +1316,5 @@ globalNameTable = Map.fromList , (resizeId , (1, genResize ) ) , (sizedIntId , (1, genSizedInt ) ) --, (tfvecId , (1, genTFVec ) ) + , (minimumId , (2, error $ "\nFunction name: \"minimum\" is used internally, use another name")) ]