2019-09-19 03:19:44 +02:00
|
|
|
{- sv2v
|
|
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
-
|
|
|
|
|
- Conversion of size casts on non-constant expressions.
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
module Convert.SizeCast (convert) where
|
|
|
|
|
|
|
|
|
|
import Control.Monad.State
|
|
|
|
|
import Control.Monad.Writer
|
|
|
|
|
import qualified Data.Map.Strict as Map
|
|
|
|
|
import qualified Data.Set as Set
|
|
|
|
|
|
|
|
|
|
import Convert.Traverse
|
|
|
|
|
import Language.SystemVerilog.AST
|
|
|
|
|
|
|
|
|
|
type TypeMap = Map.Map Identifier Type
|
2019-09-27 04:47:36 +02:00
|
|
|
type CastSet = Set.Set (Expr, Signing)
|
2019-09-19 03:19:44 +02:00
|
|
|
|
|
|
|
|
type ST = StateT TypeMap (Writer CastSet)
|
|
|
|
|
|
|
|
|
|
convert :: [AST] -> [AST]
|
|
|
|
|
convert = map convertFile
|
|
|
|
|
|
|
|
|
|
convertFile :: AST -> AST
|
|
|
|
|
convertFile descriptions =
|
|
|
|
|
descriptions' ++ map (uncurry castFn) funcs
|
|
|
|
|
where
|
|
|
|
|
results = map convertDescription descriptions
|
|
|
|
|
descriptions' = map fst results
|
|
|
|
|
funcs = Set.toList $ Set.unions $ map snd results
|
|
|
|
|
|
|
|
|
|
convertDescription :: Description -> (Description, CastSet)
|
|
|
|
|
convertDescription description =
|
|
|
|
|
(description', info)
|
|
|
|
|
where
|
|
|
|
|
(description', info) =
|
|
|
|
|
runWriter $
|
|
|
|
|
scopedConversionM traverseDeclM traverseModuleItemM traverseStmtM
|
|
|
|
|
Map.empty description
|
|
|
|
|
|
|
|
|
|
traverseDeclM :: Decl -> ST Decl
|
|
|
|
|
traverseDeclM decl = do
|
|
|
|
|
case decl of
|
|
|
|
|
Variable _ t x _ _ -> modify $ Map.insert x t
|
|
|
|
|
Param _ t x _ -> modify $ Map.insert x t
|
|
|
|
|
ParamType _ _ _ -> return ()
|
|
|
|
|
return decl
|
|
|
|
|
|
|
|
|
|
traverseModuleItemM :: ModuleItem -> ST ModuleItem
|
|
|
|
|
traverseModuleItemM item = traverseExprsM traverseExprM item
|
|
|
|
|
|
|
|
|
|
traverseStmtM :: Stmt -> ST Stmt
|
|
|
|
|
traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt
|
|
|
|
|
|
|
|
|
|
traverseExprM :: Expr -> ST Expr
|
|
|
|
|
traverseExprM =
|
|
|
|
|
traverseNestedExprsM convertExprM
|
|
|
|
|
where
|
|
|
|
|
convertExprM :: Expr -> ST Expr
|
2019-09-26 05:59:31 +02:00
|
|
|
convertExprM (Cast (Right s) e) = do
|
2019-09-19 03:19:44 +02:00
|
|
|
typeMap <- get
|
2019-09-26 05:59:31 +02:00
|
|
|
case exprSigning typeMap e of
|
|
|
|
|
Just sg -> do
|
|
|
|
|
lift $ tell $ Set.singleton (s, sg)
|
|
|
|
|
let f = castFnName s sg
|
2019-09-19 03:19:44 +02:00
|
|
|
let args = Args [Just e] []
|
|
|
|
|
return $ Call Nothing f args
|
2019-09-26 05:59:31 +02:00
|
|
|
_ -> return $ Cast (Right s) e
|
2019-09-19 03:19:44 +02:00
|
|
|
convertExprM other = return other
|
|
|
|
|
|
|
|
|
|
|
2019-09-26 05:59:31 +02:00
|
|
|
castFn :: Expr -> Signing -> Description
|
|
|
|
|
castFn e sg =
|
2019-09-19 03:19:44 +02:00
|
|
|
PackageItem $
|
|
|
|
|
Function (Just Automatic) t fnName [decl] [Return $ Ident inp]
|
|
|
|
|
where
|
|
|
|
|
inp = "inp"
|
2019-10-19 20:35:54 +02:00
|
|
|
r = (simplify $ BinOp Sub e (Number "1"), Number "0")
|
2019-09-19 03:19:44 +02:00
|
|
|
t = IntegerVector TLogic sg [r]
|
2019-09-26 05:59:31 +02:00
|
|
|
fnName = castFnName e sg
|
2019-09-19 03:19:44 +02:00
|
|
|
decl = Variable Input t inp [] Nothing
|
|
|
|
|
|
2019-09-26 05:59:31 +02:00
|
|
|
castFnName :: Expr -> Signing -> String
|
|
|
|
|
castFnName e sg =
|
|
|
|
|
if sg == Unspecified
|
|
|
|
|
then init name
|
|
|
|
|
else name
|
|
|
|
|
where
|
|
|
|
|
sizeStr = case e of
|
|
|
|
|
Number n ->
|
|
|
|
|
case readNumber n of
|
|
|
|
|
Just v -> show v
|
|
|
|
|
_ -> shortHash e
|
|
|
|
|
_ -> shortHash e
|
|
|
|
|
name = "sv2v_cast_" ++ sizeStr ++ "_" ++ show sg
|
2019-09-19 03:19:44 +02:00
|
|
|
|
|
|
|
|
exprSigning :: TypeMap -> Expr -> Maybe Signing
|
|
|
|
|
exprSigning typeMap (Ident x) =
|
|
|
|
|
case Map.lookup x typeMap of
|
|
|
|
|
Just t -> typeSigning t
|
|
|
|
|
Nothing -> Just Unspecified
|
|
|
|
|
exprSigning typeMap (BinOp op e1 e2) =
|
|
|
|
|
combiner sg1 sg2
|
|
|
|
|
where
|
|
|
|
|
sg1 = exprSigning typeMap e1
|
|
|
|
|
sg2 = exprSigning typeMap e2
|
|
|
|
|
combiner = case op of
|
|
|
|
|
BitAnd -> combineSigning
|
|
|
|
|
BitXor -> combineSigning
|
|
|
|
|
BitXnor -> combineSigning
|
|
|
|
|
BitOr -> combineSigning
|
|
|
|
|
Mul -> combineSigning
|
|
|
|
|
Div -> combineSigning
|
|
|
|
|
Add -> combineSigning
|
|
|
|
|
Sub -> combineSigning
|
|
|
|
|
Mod -> curry fst
|
|
|
|
|
Pow -> curry fst
|
|
|
|
|
ShiftAL -> curry fst
|
|
|
|
|
ShiftAR -> curry fst
|
|
|
|
|
_ -> \_ _ -> Just Unspecified
|
|
|
|
|
exprSigning _ _ = Just Unspecified
|
|
|
|
|
|
|
|
|
|
combineSigning :: Maybe Signing -> Maybe Signing -> Maybe Signing
|
|
|
|
|
combineSigning Nothing _ = Nothing
|
|
|
|
|
combineSigning _ Nothing = Nothing
|
|
|
|
|
combineSigning (Just Unspecified) msg = msg
|
|
|
|
|
combineSigning msg (Just Unspecified) = msg
|
|
|
|
|
combineSigning (Just Signed) _ = Just Signed
|
|
|
|
|
combineSigning _ (Just Signed) = Just Signed
|
|
|
|
|
combineSigning (Just Unsigned) _ = Just Unsigned
|
|
|
|
|
|
|
|
|
|
typeSigning :: Type -> Maybe Signing
|
|
|
|
|
typeSigning (Net _ sg _) = Just sg
|
|
|
|
|
typeSigning (Implicit sg _) = Just sg
|
|
|
|
|
typeSigning (IntegerVector _ sg _) = Just sg
|
|
|
|
|
typeSigning _ = Nothing
|