X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=VHDL.hs;h=9516fdd2eb137f0bc75900e13a98df52df70b191;hb=7bb29e6c00a94229f48663afb6e128d24b3ad7f9;hp=b23e5f3117acc6481e37062d2816c28754365d46;hpb=20fbdf46508998bd11da03f3abd6e8725508b0a1;p=matthijs%2Fmaster-project%2Fc%CE%BBash.git diff --git a/VHDL.hs b/VHDL.hs index b23e5f3..9516fdd 100644 --- a/VHDL.hs +++ b/VHDL.hs @@ -15,10 +15,24 @@ import Outputable ( showSDoc, ppr ) import qualified ForSyDe.Backend.VHDL.AST as AST import VHDLTypes +import Flatten import FlattenTypes import TranslatorTypes import Pretty +getDesignFile :: VHDLState AST.DesignFile +getDesignFile = do + -- Extract the library units generated from all the functions in the + -- session. + funcs <- getFuncs + let units = concat $ map getLibraryUnits funcs + let context = [ + AST.Library $ mkVHDLId "IEEE", + AST.Use $ (AST.NSimple $ mkVHDLId "IEEE.std_logic_1164") AST.:.: AST.All] + return $ AST.DesignFile + context + units + -- | Create an entity for a given function createEntity :: HsFunction -- | The function signature @@ -45,9 +59,13 @@ createEntity hsfunc fdata = in setEntity hsfunc entity' where - mkMap :: Eq id => [(id, SignalInfo)] -> id -> (AST.VHDLId, AST.TypeMark) + mkMap :: Eq id => [(id, SignalInfo)] -> id -> Maybe (AST.VHDLId, AST.TypeMark) mkMap sigmap id = - (mkVHDLId nm, vhdl_ty ty) + if isPortSigUse $ sigUse info + then + Just (mkVHDLId nm, vhdl_ty ty) + else + Nothing where info = Maybe.fromMaybe (error $ "Signal not found in the name map? This should not happen!") @@ -57,7 +75,7 @@ createEntity hsfunc fdata = (sigName info) ty = sigTy info --- | Create the VHDL AST for an entity + -- | Create the VHDL AST for an entity createEntityAST :: HsFunction -- | The signature of the function we're working with -> [VHDLSignalMap] -- | The entity's arguments @@ -70,17 +88,25 @@ createEntityAST hsfunc args res = vhdl_id = mkEntityId hsfunc ports = concatMap (mapToPorts AST.In) args ++ mapToPorts AST.Out res + ++ clk_port mapToPorts :: AST.Mode -> VHDLSignalMap -> [AST.IfaceSigDec] mapToPorts mode m = - map (mkIfaceSigDec mode) (Foldable.toList m) + Maybe.catMaybes $ map (mkIfaceSigDec mode) (Foldable.toList m) + -- Add a clk port if we have state + clk_port = if hasState hsfunc + then + [AST.IfaceSigDec (mkVHDLId "clk") AST.In VHDL.std_logic_ty] + else + [] -- | Create a port declaration mkIfaceSigDec :: AST.Mode -- | The mode for the port (In / Out) - -> (AST.VHDLId, AST.TypeMark) -- | The id and type for the port - -> AST.IfaceSigDec -- | The resulting port declaration + -> Maybe (AST.VHDLId, AST.TypeMark) -- | The id and type for the port + -> Maybe AST.IfaceSigDec -- | The resulting port declaration -mkIfaceSigDec mode (id, ty) = AST.IfaceSigDec id mode ty +mkIfaceSigDec mode (Just (id, ty)) = Just $ AST.IfaceSigDec id mode ty +mkIfaceSigDec _ Nothing = Nothing -- | Generate a VHDL entity name for the given hsfunc mkEntityId hsfunc = @@ -109,21 +135,44 @@ createArchitecture hsfunc fdata = (getEntityId fdata) -- Create signal declarations for all signals that are not in args and -- res - let sig_decs = [mkSigDec info | (id, info) <- sigs, (all (id `Foldable.notElem`) (res:args)) ] + let sig_decs = Maybe.catMaybes $ map (mkSigDec . snd) sigs -- Create component instantiations for all function applications insts <- mapM (mkCompInsSm sigs) apps + let procs = map mkStateProcSm (getOwnStates hsfunc flatfunc) let insts' = map AST.CSISm insts - let arch = AST.ArchBody (mkVHDLId "structural") (AST.NSimple entity_id) (map AST.BDISD sig_decs) insts' + let procs' = map AST.CSPSm procs + let arch = AST.ArchBody (mkVHDLId "structural") (AST.NSimple entity_id) (map AST.BDISD sig_decs) (insts' ++ procs') setArchitecture hsfunc arch -mkSigDec :: SignalInfo -> AST.SigDec +mkStateProcSm :: (Int, SignalInfo, SignalInfo) -> AST.ProcSm +mkStateProcSm (num, old, new) = + AST.ProcSm label [clk] [statement] + where + label = mkVHDLId $ "state_" ++ (show num) + clk = mkVHDLId "clk" + rising_edge = AST.NSimple $ mkVHDLId "rising_edge" + wform = AST.Wform [AST.WformElem (AST.PrimName $ AST.NSimple $ getSignalId new) Nothing] + assign = AST.SigAssign (AST.NSimple $ getSignalId 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 + +mkSigDec :: SignalInfo -> Maybe AST.SigDec mkSigDec info = - AST.SigDec (mkVHDLId name) (vhdl_ty ty) Nothing + let use = sigUse info in + if isInternalSigUse use || isStateSigUse use then + Just $ AST.SigDec (getSignalId info) (vhdl_ty ty) Nothing + else + Nothing where - name = Maybe.fromMaybe + ty = sigTy info + +-- | Creates a VHDL Id from a named SignalInfo. Errors out if the SignalInfo +-- is not named. +getSignalId :: SignalInfo -> AST.VHDLId +getSignalId info = + mkVHDLId $ Maybe.fromMaybe (error $ "Unnamed signal? This should not happen!") (sigName info) - ty = sigTy info -- | Transforms a flat function application to a VHDL component instantiation. mkCompInsSm :: @@ -153,7 +202,7 @@ mkAssocElems :: mkAssocElems sigmap app entity = -- Create the actual AssocElems - zipWith mkAssocElem ports sigs + Maybe.catMaybes $ zipWith mkAssocElem ports sigs where -- Turn the ports and signals from a map into a flat list. This works, -- since the maps must have an identical form by definition. TODO: Check @@ -163,7 +212,7 @@ mkAssocElems sigmap app entity = arg_sigs = (concat (map Foldable.toList (appArgs app))) res_sigs = Foldable.toList (appRes app) -- Extract the id part from the (id, type) tuple - ports = (map fst (arg_ports ++ res_ports)) + ports = (map (fmap fst) (arg_ports ++ res_ports)) -- Translate signal numbers into names sigs = (map (lookupSigName sigmap) (arg_sigs ++ res_sigs)) @@ -179,8 +228,9 @@ lookupSigName sigs sig = name (sigName info) -- | Create an VHDL port -> signal association -mkAssocElem :: AST.VHDLId -> String -> AST.AssocElem -mkAssocElem port signal = Just port AST.:=>: (AST.ADName (AST.NSimple (mkVHDLId signal))) +mkAssocElem :: Maybe AST.VHDLId -> String -> Maybe AST.AssocElem +mkAssocElem (Just port) signal = Just $ Just port AST.:=>: (AST.ADName (AST.NSimple (mkVHDLId signal))) +mkAssocElem Nothing _ = Nothing -- | Extracts the generated entity id from the given funcdata getEntityId :: FuncData -> Maybe AST.VHDLId @@ -210,6 +260,10 @@ getLibraryUnits (hsfunc, fdata) = bit_ty :: AST.TypeMark bit_ty = AST.unsafeVHDLBasicId "Bit" +-- | The VHDL std_logic +std_logic_ty :: AST.TypeMark +std_logic_ty = AST.unsafeVHDLBasicId "std_logic" + -- Translate a Haskell type to a VHDL type vhdl_ty :: Type.Type -> AST.TypeMark vhdl_ty ty = Maybe.fromMaybe