+ if (TyCon.isTupleTyCon tycon) then
+ -- Expand tuples we find
+ Tuple (getPortNameMapForTys name 0 args)
+ else -- Assume it's a type constructor application, ie simple data type
+ -- TODO: Add type?
+ Signal name
+ where
+ (tycon, args) = Type.splitTyConApp ty
+
+data HWFunction = HWFunction { -- A function that is available in hardware
+ inPorts :: [SignalNameMap String],
+ outPort :: SignalNameMap String
+ --entity :: AST.EntityDec
+} deriving (Show)
+
+-- Turns a CoreExpr describing a function into a description of its input and
+-- output ports.
+mkHWFunction ::
+ CoreBind -- The core binder to generate the interface for
+ -> VHDLState (String, HWFunction) -- The name of the function and its interface
+
+mkHWFunction (NonRec var expr) =
+ return (name, HWFunction inports outport)
+ where
+ name = (getOccString var)
+ ty = CoreUtils.exprType expr
+ (fargs, res) = Type.splitFunTys ty
+ args = if length fargs == 1 then fargs else (init fargs)
+ --state = if length fargs == 1 then () else (last fargs)
+ inports = case args of
+ -- Handle a single port specially, to prevent an extra 0 in the name
+ [port] -> [getPortNameMapForTy "portin" port]
+ ps -> getPortNameMapForTys "portin" 0 ps
+ outport = getPortNameMapForTy "portout" res
+
+mkHWFunction (Rec _) =
+ error "Recursive binders not supported"
+
+data VHDLSession = VHDLSession {
+ nameCount :: Int, -- A counter that can be used to generate unique names
+ funcs :: [(String, HWFunction)] -- All functions available, indexed by name
+} deriving (Show)
+
+type VHDLState = State.State VHDLSession
+
+-- Add the function to the session
+addFunc :: String -> HWFunction -> VHDLState ()
+addFunc name f = do
+ fs <- State.gets funcs -- Get the funcs element from the session
+ State.modify (\x -> x {funcs = (name, f) : fs }) -- Prepend name and f
+
+-- Lookup the function with the given name in the current session. Errors if
+-- it was not found.
+getHWFunc :: String -> VHDLState HWFunction
+getHWFunc name = do
+ fs <- State.gets funcs -- Get the funcs element from the session
+ return $ Maybe.fromMaybe
+ (error $ "Function " ++ name ++ "is unknown? This should not happen!")
+ (lookup name fs)
+
+-- Makes the given name unique by appending a unique number.
+-- This does not do any checking against existing names, so it only guarantees
+-- uniqueness with other names generated by uniqueName.
+uniqueName :: String -> VHDLState String
+uniqueName name = do
+ count <- State.gets nameCount -- Get the funcs element from the session
+ State.modify (\s -> s {nameCount = count + 1})
+ return $ name ++ "-" ++ (show count)
+
+builtin_funcs =
+ [
+ ("hwxor", HWFunction [Signal "a", Signal "b"] (Signal "o")),
+ ("hwand", HWFunction [Signal "a", Signal "b"] (Signal "o"))
+ ]
+
+-- vim: set ts=8 sw=2 sts=2 expandtab: