- AST.CSSASm assign
- where
- vhdl_expr (Left id) = mkIdExpr sigs id
- vhdl_expr (Right expr) =
- case expr of
- (EqLit id lit) ->
- (mkIdExpr sigs id) AST.:=: (AST.PrimLit lit)
- (Literal lit) ->
- AST.PrimLit lit
- (Eq a b) ->
- (mkIdExpr sigs a) AST.:=: (mkIdExpr sigs b)
-
-mkConcSm _ sigs (CondDef cond true false dst) _ =
- let
- cond_expr = mkIdExpr sigs cond
- true_expr = mkIdExpr sigs true
- false_expr = mkIdExpr sigs false
- false_wform = AST.Wform [AST.WformElem false_expr Nothing]
- true_wform = AST.Wform [AST.WformElem true_expr Nothing]
- whenelse = AST.WhenElse true_wform cond_expr
- dst_name = AST.NSimple (getSignalId $ signalInfo sigs dst)
- assign = dst_name AST.:<==: (AST.ConWforms [whenelse] false_wform Nothing)
- in
- AST.CSSASm assign
-
--- | Turn a SignalId into a VHDL Expr
-mkIdExpr :: [(SignalId, SignalInfo)] -> SignalId -> AST.Expr
-mkIdExpr sigs id =
- let src_name = AST.NSimple (getSignalId $ signalInfo sigs id) in
- AST.PrimName src_name
-
-mkAssocElems ::
- [(SignalId, SignalInfo)] -- | The signals in the current architecture
- -> [SignalMap] -- | The signals that are applied to function
- -> SignalMap -- | the signals in which to store the function result
- -> Entity -- | The entity to map against.
- -> [AST.AssocElem] -- | The resulting port maps
-
-mkAssocElems sigmap args res entity =
- -- Create the actual AssocElems
- 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
- -- the similar form?
- arg_ports = concat (map Foldable.toList (ent_args entity))
- res_ports = Foldable.toList (ent_res entity)
- arg_sigs = (concat (map Foldable.toList args))
- res_sigs = Foldable.toList res
- -- Extract the id part from the (id, type) tuple
- ports = (map (fmap fst) (arg_ports ++ res_ports))
- -- Translate signal numbers into names
- sigs = (map (lookupSigName sigmap) (arg_sigs ++ res_sigs))
-
--- | Look up a signal in the signal name map
-lookupSigName :: [(SignalId, SignalInfo)] -> SignalId -> String
-lookupSigName sigs sig = name
- where
- info = Maybe.fromMaybe
- (error $ "Unknown signal " ++ (show sig) ++ " used? This should not happen!")
- (lookup sig sigs)
- name = Maybe.fromMaybe
- (error $ "Unnamed signal " ++ (show sig) ++ " used? This should not happen!")
- (sigName info)
-
--- | Create an VHDL port -> signal association
-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
-
--- | The VHDL Bit type
-bit_ty :: AST.TypeMark
-bit_ty = AST.unsafeVHDLBasicId "Bit"
-
--- | The VHDL Boolean type
-bool_ty :: AST.TypeMark
-bool_ty = AST.unsafeVHDLBasicId "Boolean"
-
--- | 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.TypeDec], AST.TypeMark)
-vhdl_ty ty = Maybe.fromMaybe
- (error $ "Unsupported Haskell type: " ++ (showSDoc $ ppr ty))
- (vhdl_ty_maybe ty)
-
--- Translate a Haskell type to a VHDL type, optionally generating a type
--- declaration for the type.
-vhdl_ty_maybe :: Type.Type -> Maybe ([AST.TypeDec], AST.TypeMark)
-vhdl_ty_maybe ty =
- if Type.coreEqType ty TysWiredIn.boolTy
- then
- Just ([], bool_ty)
- else
- case Type.splitTyConApp_maybe ty of
- Just (tycon, args) ->
- let name = TyCon.tyConName tycon in
- -- TODO: Do something more robust than string matching
- case Name.getOccString name of
- "Bit" -> Just ([], std_logic_ty)
- "FSVec" ->
- let
- [len, el_ty] = args
- -- TODO: Find actual number
- ty_id = mkVHDLId ("vector_" ++ (show len))
- -- TODO: Use el_ty
- range = AST.IndexConstraint [AST.ToRange (AST.PrimLit "0") (AST.PrimLit "16")]
- ty_def = AST.TDA $ AST.ConsArrayDef range std_logic_ty
- ty_dec = AST.TypeDec ty_id ty_def
- in
- Just ([ty_dec], ty_id)
- otherwise -> Nothing
- otherwise -> Nothing
-
--- Shortcut
-mkVHDLId :: String -> AST.VHDLId
-mkVHDLId s =
- AST.unsafeVHDLBasicId $ (strip_multiscore . strip_invalid) s
- where
- -- Strip invalid characters.
- strip_invalid = filter (`elem` ['A'..'Z'] ++ ['a'..'z'] ++ ['0'..'9'] ++ "_.")
- -- Strip multiple adjacent underscores
- strip_multiscore = concat . map (\cs ->
- case cs of
- ('_':_) -> "_"
- _ -> cs
- ) . List.group