Remove defunct makeVHDLStrings function, messes with haddock
[matthijs/master-project/cλash.git] / cλash / CLasH / Translator.hs
index caa02071dbd6dcf9c476e18d24c493b7af398fae..6177dabaca9fc069374da39caf6995e4f8c69ba7 100644 (file)
-{-# LANGUAGE ScopedTypeVariables #-}
+module CLasH.Translator 
+  (
+   makeVHDLAnnotations
+  ) where
 
-module CLasH.Translator where
-
-import qualified Directory
-import qualified System.FilePath as FilePath
-import qualified List
-import Debug.Trace
-import qualified Control.Arrow as Arrow
-import GHC hiding (loadModule, sigName)
-import CoreSyn
-import qualified CoreUtils
-import qualified Var
-import qualified Type
-import qualified TyCon
-import qualified DataCon
-import qualified HscMain
-import qualified SrcLoc
-import qualified FastString
+-- Standard Modules
+import qualified System.Directory as Directory
 import qualified Maybe
-import qualified Module
-import qualified Data.Foldable as Foldable
+import qualified Monad
+import qualified System.FilePath as FilePath
 import qualified Control.Monad.Trans.State as State
-import qualified Control.Monad as Monad
-import Name
+import Text.PrettyPrint.HughesPJ (render)
+import Data.Accessor.Monad.Trans.State
 import qualified Data.Map as Map
-import Data.Accessor
-import Data.Generics
-import NameEnv ( lookupNameEnv )
+import qualified Data.Time.Clock as Clock
+import Debug.Trace
+
+-- GHC API
+import qualified CoreSyn
 import qualified HscTypes
-import HscTypes ( cm_binds, cm_types )
-import MonadUtils ( liftIO )
-import Outputable ( showSDoc, ppr, showSDocDebug )
-import DynFlags ( defaultDynFlags )
 import qualified UniqSupply
-import List ( find )
-import qualified List
-import qualified Monad
-import qualified Annotations
-import qualified Serialized
 
--- The following modules come from the ForSyDe project. They are really
--- internal modules, so ForSyDe.cabal has to be modified prior to installing
--- ForSyDe to get access to these modules.
+-- VHDL Imports
 import qualified Language.VHDL.AST as AST
-import qualified Language.VHDL.FileIO
+import qualified Language.VHDL.FileIO as FileIO
 import qualified Language.VHDL.Ppr as Ppr
--- This is needed for rendering the pretty printed VHDL
-import Text.PrettyPrint.HughesPJ (render)
 
+-- Local Imports
 import CLasH.Translator.TranslatorTypes
 import CLasH.Translator.Annotations
-import CLasH.Utils.Pretty
-import CLasH.Normalize
-import CLasH.VHDL.VHDLTypes
-import qualified CLasH.VHDL as VHDL
-
-makeVHDL :: FilePath -> String -> String -> Bool -> IO ()
-makeVHDL libdir filename name stateful = do
-  -- Load the module
-  (core, env) <- loadModule libdir filename
+import CLasH.Utils
+import CLasH.Utils.GhcTools
+import CLasH.VHDL
+import CLasH.VHDL.VHDLTools
+import CLasH.VHDL.Testbench
+
+-- | Turn Haskell to VHDL, Using the Annotations for Top Entity, Initial State
+--   and Test Inputs found in the Files. 
+makeVHDLAnnotations :: 
+  FilePath      -- ^ The GHC Library Dir
+  -> [FilePath] -- ^ The FileNames
+  -> IO ()
+makeVHDLAnnotations libdir filenames =
+  makeVHDL libdir filenames finder
+    where
+      finder = findSpec (hasCLasHAnnotation isTopEntity)
+                        (hasCLasHAnnotation isInitState)
+                        (isCLasHAnnotation isInitState)
+                        (hasCLasHAnnotation isTestInput)
+
+-- | Turn Haskell to VHDL, using the given finder functions to find the Top
+--   Entity, Initial State and Test Inputs in the Haskell Files.
+makeVHDL ::
+  FilePath      -- ^ The GHC Library Dir
+  -> [FilePath] -- ^ The Filenames
+  -> Finder
+  -> IO ()
+makeVHDL libdir filenames finder = do
+  start <- Clock.getCurrentTime
+  -- Load the modules
+  (cores, env, specs) <- loadModules libdir filenames (Just finder)
   -- Translate to VHDL
-  vhdl <- moduleToVHDL env core [(name, stateful)]
-  -- Write VHDL to file
-  let dir = "./vhdl/" ++ name ++ "/"
-  prepareDir dir
-  mapM (writeVHDL dir) vhdl
-  return ()
-  
-makeVHDLAnn :: FilePath -> String -> IO ()
-makeVHDLAnn libdir filename = do
-  (core, top, init, env) <- loadModuleAnn libdir filename
-  let top_entity = head top
-  vhdl <- case init of 
-    [] -> moduleToVHDLAnn env core [top_entity]
-    xs -> moduleToVHDLAnnState env core [(top_entity, (head xs))]
+  vhdl <- moduleToVHDL env cores specs
+  -- Write VHDL to file. Just use the first entity for the name
+  let top_entity = head $ Maybe.catMaybes $ map (\(t, _, _) -> t) specs
   let dir = "./vhdl/" ++ (show top_entity) ++ "/"
   prepareDir dir
-  mapM (writeVHDL dir) vhdl
-  return ()
-
-listBindings :: FilePath -> String -> IO [()]
-listBindings libdir filename = do
-  (core, env) <- loadModule libdir filename
-  let binds = CoreSyn.flattenBinds $ cm_binds core
-  mapM (listBinding) binds
-
-listBinding :: (CoreBndr, CoreExpr) -> IO ()
-listBinding (b, e) = do
-  putStr "\nBinder: "
-  putStr $ show b
-  putStr "\nType of Binder: \n"
-  putStr $ showSDoc $ ppr $ Var.varType b
-  putStr "\n\nExpression: \n"
-  putStr $ prettyShow e
-  putStr "\n\n"
-  putStr $ showSDoc $ ppr e
-  putStr "\n\nType of Expression: \n"
-  putStr $ showSDoc $ ppr $ CoreUtils.exprType e
-  putStr "\n\n"
-  
--- | Show the core structure of the given binds in the given file.
-listBind :: FilePath -> String -> String -> IO ()
-listBind libdir filename name = do
-  (core, env) <- loadModule libdir filename
-  let [(b, expr)] = findBinds core [name]
-  listBinding (b, expr)
-
--- | Translate the binds with the given names from the given core module to
---   VHDL. The Bool in the tuple makes the function stateful (True) or
---   stateless (False).
-moduleToVHDL :: HscTypes.HscEnv -> HscTypes.CoreModule -> [(String, Bool)] -> IO [(AST.VHDLId, AST.DesignFile)]
-moduleToVHDL env core list = do
-  let (names, statefuls) = unzip list
-  let binds = map fst $ findBinds core names
-  -- Generate a UniqSupply
-  -- Running 
-  --    egrep -r "(initTcRnIf|mkSplitUniqSupply)" .
-  -- on the compiler dir of ghc suggests that 'z' is not used to generate a
-  -- unique supply anywhere.
-  uniqSupply <- UniqSupply.mkSplitUniqSupply 'z'
-  -- Turn bind into VHDL
-  let all_bindings = (CoreSyn.flattenBinds $ cm_binds core)
-  let (normalized_bindings, typestate) = normalizeModule env uniqSupply all_bindings binds statefuls
-  let vhdl = VHDL.createDesignFiles typestate normalized_bindings
-  mapM (putStr . render . Ppr.ppr . snd) vhdl
-  --putStr $ "\n\nFinal session:\n" ++ prettyShow sess ++ "\n\n"
+  mapM_ (writeVHDL dir) vhdl
+  end <- Clock.getCurrentTime
+  trace ("\nTotal compilation took " ++ show (Clock.diffUTCTime end start)) $
+    return ()
+
+-- | Translate the specified entities in the given modules to VHDL.
+moduleToVHDL ::
+  HscTypes.HscEnv             -- ^ The GHC Environment
+  -> [HscTypes.CoreModule]    -- ^ The Core Modules
+  -> [EntitySpec]             -- ^ The entities to generate
+  -> IO [(AST.VHDLId, AST.DesignFile)]
+moduleToVHDL env cores specs = do
+  (vhdl, count) <- runTranslatorSession env $ do
+    let all_bindings = concatMap (\x -> CoreSyn.flattenBinds (HscTypes.cm_binds x)) cores
+    -- Store the bindings we loaded
+    tsBindings %= Map.fromList all_bindings
+    let all_initstates = concatMap (\x -> case x of (_, Nothing, _) -> []; (_, Just inits, _) -> inits) specs 
+    tsInitStates %= Map.fromList all_initstates
+    test_binds <- catMaybesM $ Monad.mapM mkTest specs
+    let topbinds = Maybe.catMaybes $ map (\(top, _, _) -> top) specs
+    vhdl <- case topbinds of
+      []  -> error "Could not find top entity requested"
+      tops -> createDesignFiles (tops ++ test_binds)
+    count <- get tsTransformCounter 
+    return (vhdl, count)
+  mapM_ (putStr . render . Ppr.ppr . snd) vhdl
+  putStr $ "Total number of transformations applied: " ++ (show count) ++ "\n"
   return vhdl
-  
-moduleToVHDLAnn :: HscTypes.HscEnv -> HscTypes.CoreModule -> [CoreSyn.CoreBndr] -> IO [(AST.VHDLId, AST.DesignFile)]
-moduleToVHDLAnn env core binds = do
+  where
+    mkTest :: EntitySpec -> TranslatorSession (Maybe CoreSyn.CoreBndr)
+    -- Create a testbench for any entry that has test input
+    mkTest (_, _, Nothing) = return Nothing
+    mkTest (Nothing, _, _) = return Nothing
+    mkTest (Just top, _, Just input) = do
+      bndr <- createTestbench Nothing cores input top
+      return $ Just bndr
+
+-- Run the given translator session. Generates a new UniqSupply for that
+-- session.
+runTranslatorSession :: HscTypes.HscEnv -> TranslatorSession a -> IO a
+runTranslatorSession env session = do
   -- Generate a UniqSupply
   -- Running 
   --    egrep -r "(initTcRnIf|mkSplitUniqSupply)" .
-  -- on the compiler dir of ghc suggests that 'z' is not used to generate a
-  -- unique supply anywhere.
+  -- on the compiler dir of ghc suggests that 'z' is not used to generate
+  -- unique supply anywhere.
   uniqSupply <- UniqSupply.mkSplitUniqSupply 'z'
-  -- Turn bind into VHDL
-  let all_bindings = (CoreSyn.flattenBinds $ cm_binds core)
-  let (normalized_bindings, typestate) = normalizeModule env uniqSupply all_bindings binds [False]
-  let vhdl = VHDL.createDesignFiles typestate normalized_bindings
-  mapM (putStr . render . Ppr.ppr . snd) vhdl
-  --putStr $ "\n\nFinal session:\n" ++ prettyShow sess ++ "\n\n"
-  return vhdl
-  
-moduleToVHDLAnnState :: HscTypes.HscEnv -> HscTypes.CoreModule -> [(CoreSyn.CoreBndr, CoreSyn.CoreBndr)] -> IO [(AST.VHDLId, AST.DesignFile)]
-moduleToVHDLAnnState env core list = do
-  let (binds, init_states) = unzip list
-  -- Generate a UniqSupply
-  -- Running 
-  --    egrep -r "(initTcRnIf|mkSplitUniqSupply)" .
-  -- on the compiler dir of ghc suggests that 'z' is not used to generate a
-  -- unique supply anywhere.
-  uniqSupply <- UniqSupply.mkSplitUniqSupply 'z'
-  -- Turn bind into VHDL
-  let all_bindings = (CoreSyn.flattenBinds $ cm_binds core)
-  let (normalized_bindings, typestate) = normalizeModule env uniqSupply all_bindings binds [True]
-  let vhdl = VHDL.createDesignFiles typestate normalized_bindings
-  mapM (putStr . render . Ppr.ppr . snd) vhdl
-  --putStr $ "\n\nFinal session:\n" ++ prettyShow sess ++ "\n\n"
-  return vhdl
+  let init_typestate = TypeState builtin_types [] Map.empty Map.empty env
+  let init_state = TranslatorState uniqSupply init_typestate Map.empty Map.empty 0 Map.empty Map.empty Map.empty 0
+  return $ State.evalState session init_state
 
 -- | Prepares the directory for writing VHDL files. This means creating the
 --   dir if it does not exist and removing all existing .vhdl files from it.
 prepareDir :: String -> IO()
 prepareDir dir = do
   -- Create the dir if needed
-  exists <- Directory.doesDirectoryExist dir
-  Monad.unless exists $ Directory.createDirectory dir
+  Directory.createDirectoryIfMissing True dir
   -- Find all .vhdl files in the directory
   files <- Directory.getDirectoryContents dir
   let to_remove = filter ((==".vhdl") . FilePath.takeExtension) files
@@ -182,287 +137,6 @@ writeVHDL dir (name, vhdl) = do
   -- Find the filename
   let fname = dir ++ (AST.fromVHDLId name) ++ ".vhdl"
   -- Write the file
-  Language.VHDL.FileIO.writeDesignFile vhdl fname
-
--- | Loads the given file and turns it into a core module.
-loadModule :: FilePath -> String -> IO (HscTypes.CoreModule, HscTypes.HscEnv)
-loadModule libdir filename =
-  defaultErrorHandler defaultDynFlags $ do
-    runGhc (Just libdir) $ do
-      dflags <- getSessionDynFlags
-      setSessionDynFlags dflags
-      --target <- guessTarget "adder.hs" Nothing
-      --liftIO (print (showSDoc (ppr (target))))
-      --liftIO $ printTarget target
-      --setTargets [target]
-      --load LoadAllTargets
-      --core <- GHC.compileToCoreSimplified "Adders.hs"
-      core <- GHC.compileToCoreModule filename
-      env <- GHC.getSession
-      return (core, env)
-      
--- | Loads the given file and turns it into a core module.
-loadModuleAnn :: FilePath -> String -> IO (HscTypes.CoreModule, [CoreSyn.CoreBndr], [CoreSyn.CoreBndr], HscTypes.HscEnv)
-loadModuleAnn libdir filename =
-  defaultErrorHandler defaultDynFlags $ do
-    runGhc (Just libdir) $ do
-      dflags <- getSessionDynFlags
-      setSessionDynFlags dflags
-      --target <- guessTarget "adder.hs" Nothing
-      --liftIO (print (showSDoc (ppr (target))))
-      --liftIO $ printTarget target
-      --setTargets [target]
-      --load LoadAllTargets
-      --core <- GHC.compileToCoreSimplified "Adders.hs"
-      core <- GHC.compileToCoreModule filename
-      env <- GHC.getSession
-      top_entity <- findTopEntity core
-      init_state <- findInitState core
-      return (core, top_entity, init_state, env)
-
-findTopEntity :: GhcMonad m => HscTypes.CoreModule -> m [CoreSyn.CoreBndr]
-findTopEntity core = do
-  let binds = CoreSyn.flattenBinds $ cm_binds core
-  topbinds <- Monad.filterM (hasTopEntityAnnotation . fst) binds
-  let bndrs = case topbinds of [] -> error $ "Couldn't find top entity in current module." ; xs -> fst (unzip topbinds)
-  return bndrs
-  
-findInitState :: GhcMonad m => HscTypes.CoreModule -> m [CoreSyn.CoreBndr]
-findInitState core = do
-  let binds = CoreSyn.flattenBinds $ cm_binds core
-  statebinds <- Monad.filterM (hasInitStateAnnotation . fst) binds
-  let bndrs = case statebinds of [] -> [] ; xs -> fst (unzip statebinds)
-  return bndrs
-  
-hasTopEntityAnnotation :: GhcMonad m => Var.Var -> m Bool
-hasTopEntityAnnotation var = do
-  let deserializer = Serialized.deserializeWithData
-  let target = Annotations.NamedTarget (Var.varName var)
-  (anns :: [CLasHAnn]) <- GHC.findGlobalAnns deserializer target
-  let top_ents = filter isTopEntity anns
-  case top_ents of
-    [] -> return False
-    xs -> return True
-    
-hasInitStateAnnotation :: GhcMonad m => Var.Var -> m Bool
-hasInitStateAnnotation var = do
-  let deserializer = Serialized.deserializeWithData
-  let target = Annotations.NamedTarget (Var.varName var)
-  (anns :: [CLasHAnn]) <- GHC.findGlobalAnns deserializer target
-  let top_ents = filter isInitState anns
-  case top_ents of
-    [] -> return False
-    xs -> return True
-
--- | Extracts the named binds from the given module.
-findBinds :: HscTypes.CoreModule -> [String] -> [(CoreBndr, CoreExpr)]
-findBinds core names = Maybe.mapMaybe (findBind (CoreSyn.flattenBinds $ cm_binds core)) names
-
--- | Extract a named bind from the given list of binds
-findBind :: [(CoreBndr, CoreExpr)] -> String -> Maybe (CoreBndr, CoreExpr)
-findBind binds lookfor =
-  -- This ignores Recs and compares the name of the bind with lookfor,
-  -- disregarding any namespaces in OccName and extra attributes in Name and
-  -- Var.
-  find (\(var, _) -> lookfor == (occNameString $ nameOccName $ getName var)) binds
-
--- | Flattens the given bind into the given signature and adds it to the
---   session. Then (recursively) finds any functions it uses and does the same
---   with them.
--- flattenBind ::
---   HsFunction                         -- The signature to flatten into
---   -> (CoreBndr, CoreExpr)            -- The bind to flatten
---   -> TranslatorState ()
--- 
--- flattenBind hsfunc bind@(var, expr) = do
---   -- Flatten the function
---   let flatfunc = flattenFunction hsfunc bind
---   -- Propagate state variables
---   let flatfunc' = propagateState hsfunc flatfunc
---   -- Store the flat function in the session
---   modA tsFlatFuncs (Map.insert hsfunc flatfunc')
---   -- Flatten any functions used
---   let used_hsfuncs = Maybe.mapMaybe usedHsFunc (flat_defs flatfunc')
---   mapM_ resolvFunc used_hsfuncs
-
--- | Decide which incoming state variables will become state in the
---   given function, and which will be propagate to other applied
---   functions.
--- propagateState ::
---   HsFunction
---   -> FlatFunction
---   -> FlatFunction
--- 
--- propagateState hsfunc flatfunc =
---     flatfunc {flat_defs = apps', flat_sigs = sigs'} 
---   where
---     (olds, news) = unzip $ getStateSignals hsfunc flatfunc
---     states' = zip olds news
---     -- Find all signals used by all sigdefs
---     uses = concatMap sigDefUses (flat_defs flatfunc)
---     -- Find all signals that are used more than once (is there a
---     -- prettier way to do this?)
---     multiple_uses = uses List.\\ (List.nub uses)
---     -- Find the states whose "old state" signal is used only once
---     single_use_states = filter ((`notElem` multiple_uses) . fst) states'
---     -- See if these single use states can be propagated
---     (substate_sigss, apps') = unzip $ map (propagateState' single_use_states) (flat_defs flatfunc)
---     substate_sigs = concat substate_sigss
---     -- Mark any propagated state signals as SigSubState
---     sigs' = map 
---       (\(id, info) -> (id, if id `elem` substate_sigs then info {sigUse = SigSubState} else info))
---       (flat_sigs flatfunc)
-
--- | Propagate the state into a single function application.
--- propagateState' ::
---   [(SignalId, SignalId)]
---                       -- ^ TODO
---   -> SigDef           -- ^ The SigDef to process.
---   -> ([SignalId], SigDef) 
---                       -- ^ Any signal ids that should become substates,
---                       --   and the resulting application.
--- 
--- propagateState' states def =
---     if (is_FApp def) then
---       (our_old ++ our_new, def {appFunc = hsfunc'})
---     else
---       ([], def)
---   where
---     hsfunc = appFunc def
---     args = appArgs def
---     res = appRes def
---     our_states = filter our_state states
---     -- A state signal belongs in this function if the old state is
---     -- passed in, and the new state returned
---     our_state (old, new) =
---       any (old `Foldable.elem`) args
---       && new `Foldable.elem` res
---     (our_old, our_new) = unzip our_states
---     -- Mark the result
---     zipped_res = zipValueMaps res (hsFuncRes hsfunc)
---     res' = fmap (mark_state (zip our_new [0..])) zipped_res
---     -- Mark the args
---     zipped_args = zipWith zipValueMaps args (hsFuncArgs hsfunc)
---     args' = map (fmap (mark_state (zip our_old [0..]))) zipped_args
---     hsfunc' = hsfunc {hsFuncArgs = args', hsFuncRes = res'}
--- 
---     mark_state :: [(SignalId, StateId)] -> (SignalId, HsValueUse) -> HsValueUse
---     mark_state states (id, use) =
---       case lookup id states of
---         Nothing -> use
---         Just state_id -> State state_id
-
--- | Returns pairs of signals that should be mapped to state in this function.
--- getStateSignals ::
---   HsFunction                      -- | The function to look at
---   -> FlatFunction                 -- | The function to look at
---   -> [(SignalId, SignalId)]   
---         -- | TODO The state signals. The first is the state number, the second the
---         --   signal to assign the current state to, the last is the signal
---         --   that holds the new state.
--- 
--- getStateSignals hsfunc flatfunc =
---   [(old_id, new_id) 
---     | (old_num, old_id) <- args
---     , (new_num, new_id) <- res
---     , old_num == new_num]
---   where
---     sigs = flat_sigs flatfunc
---     -- Translate args and res to lists of (statenum, sigid)
---     args = concat $ zipWith stateList (hsFuncArgs hsfunc) (flat_args flatfunc)
---     res = stateList (hsFuncRes hsfunc) (flat_res flatfunc)
-    
--- | Find the given function, flatten it and add it to the session. Then
---   (recursively) do the same for any functions used.
--- resolvFunc ::
---   HsFunction        -- | The function to look for
---   -> TranslatorState ()
--- 
--- resolvFunc hsfunc = do
---   flatfuncmap <- getA tsFlatFuncs
---   -- Don't do anything if there is already a flat function for this hsfunc or
---   -- when it is a builtin function.
---   Monad.unless (Map.member hsfunc flatfuncmap) $ do
---   -- Not working with new builtins -- Monad.unless (elem hsfunc VHDL.builtin_hsfuncs) $ do
---   -- New function, resolve it
---   core <- getA tsCoreModule
---   -- Find the named function
---   let name = (hsFuncName hsfunc)
---   let bind = findBind (CoreSyn.flattenBinds $ cm_binds core) name 
---   case bind of
---     Nothing -> error $ "Couldn't find function " ++ name ++ " in current module."
---     Just b  -> flattenBind hsfunc b
-
--- | Translate a top level function declaration to a HsFunction. i.e., which
---   interface will be provided by this function. This function essentially
---   defines the "calling convention" for hardware models.
--- mkHsFunction ::
---   Var.Var         -- ^ The function defined
---   -> Type         -- ^ The function type (including arguments!)
---   -> Bool         -- ^ Is this a stateful function?
---   -> HsFunction   -- ^ The resulting HsFunction
--- 
--- mkHsFunction f ty stateful=
---   HsFunction hsname hsargs hsres
---   where
---     hsname  = getOccString f
---     (arg_tys, res_ty) = Type.splitFunTys ty
---     (hsargs, hsres) = 
---       if stateful 
---       then
---         let
---           -- The last argument must be state
---           state_ty = last arg_tys
---           state    = useAsState (mkHsValueMap state_ty)
---           -- All but the last argument are inports
---           inports = map (useAsPort . mkHsValueMap)(init arg_tys)
---           hsargs   = inports ++ [state]
---           hsres    = case splitTupleType res_ty of
---             -- Result type must be a two tuple (state, ports)
---             Just [outstate_ty, outport_ty] -> if Type.coreEqType state_ty outstate_ty
---               then
---                 Tuple [state, useAsPort (mkHsValueMap outport_ty)]
---               else
---                 error $ "Input state type of function " ++ hsname ++ ": " ++ (showSDoc $ ppr state_ty) ++ " does not match output state type: " ++ (showSDoc $ ppr outstate_ty)
---             otherwise                -> error $ "Return type of top-level function " ++ hsname ++ " must be a two-tuple containing a state and output ports."
---         in
---           (hsargs, hsres)
---       else
---         -- Just use everything as a port
---         (map (useAsPort . mkHsValueMap) arg_tys, useAsPort $ mkHsValueMap res_ty)
-
--- | Adds signal names to the given FlatFunction
--- nameFlatFunction ::
---   FlatFunction
---   -> FlatFunction
--- 
--- nameFlatFunction flatfunc =
---   -- Name the signals
---   let 
---     s = flat_sigs flatfunc
---     s' = map nameSignal s in
---   flatfunc { flat_sigs = s' }
---   where
---     nameSignal :: (SignalId, SignalInfo) -> (SignalId, SignalInfo)
---     nameSignal (id, info) =
---       let hints = nameHints info in
---       let parts = ("sig" : hints) ++ [show id] in
---       let name = concat $ List.intersperse "_" parts in
---       (id, info {sigName = Just name})
--- 
--- -- | Splits a tuple type into a list of element types, or Nothing if the type
--- --   is not a tuple type.
--- splitTupleType ::
---   Type              -- ^ The type to split
---   -> Maybe [Type]   -- ^ The tuples element types
--- 
--- splitTupleType ty =
---   case Type.splitTyConApp_maybe ty of
---     Just (tycon, args) -> if TyCon.isTupleTyCon tycon 
---       then
---         Just args
---       else
---         Nothing
---     Nothing -> Nothing
+  FileIO.writeDesignFile vhdl fname
 
 -- vim: set ts=8 sw=2 sts=2 expandtab: