2019-03-19 18:40:25 +01:00
|
|
|
{- sv2v
|
|
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
-
|
|
|
|
|
- Conversion for unbased, unsized literals ('0, '1, 'z, 'x)
|
|
|
|
|
-
|
2020-06-15 03:43:32 +02:00
|
|
|
- The literals are given a binary base and are made signed to allow sign
|
|
|
|
|
- extension. This enables the desired implicit casting in Verilog-2005.
|
|
|
|
|
- However, in self-determined contextes, the literals are given an explicit
|
|
|
|
|
- size of 1.
|
2019-03-19 18:40:25 +01:00
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
module Convert.UnbasedUnsized (convert) where
|
|
|
|
|
|
|
|
|
|
import Convert.Traverse
|
|
|
|
|
import Language.SystemVerilog.AST
|
|
|
|
|
|
2019-04-24 00:44:45 +02:00
|
|
|
convert :: [AST] -> [AST]
|
2020-06-15 03:43:32 +02:00
|
|
|
convert = map $ traverseDescriptions $ traverseModuleItems convertModuleItem
|
|
|
|
|
|
|
|
|
|
convertModuleItem :: ModuleItem -> ModuleItem
|
|
|
|
|
convertModuleItem =
|
|
|
|
|
traverseExprs (traverseNestedExprs convertExpr) .
|
|
|
|
|
traverseStmts (traverseNestedStmts convertStmt) .
|
|
|
|
|
traverseTypes (traverseNestedTypes convertType)
|
2019-03-19 18:40:25 +01:00
|
|
|
|
|
|
|
|
digits :: [Char]
|
|
|
|
|
digits = ['0', '1', 'x', 'z', 'X', 'Z']
|
|
|
|
|
|
2020-06-15 03:43:32 +02:00
|
|
|
literalFor :: String -> Char -> Expr
|
|
|
|
|
literalFor prefix ch =
|
2019-03-19 18:40:25 +01:00
|
|
|
if elem ch digits
|
2020-06-15 03:43:32 +02:00
|
|
|
then Number (prefix ++ [ch])
|
2019-03-19 18:40:25 +01:00
|
|
|
else error $ "unexpected unbased-unsized digit: " ++ [ch]
|
2020-06-06 03:40:59 +02:00
|
|
|
|
2020-06-15 03:43:32 +02:00
|
|
|
sizedLiteralFor :: Char -> Expr
|
|
|
|
|
sizedLiteralFor = literalFor "1'sb"
|
|
|
|
|
|
|
|
|
|
unsizedLiteralFor :: Char -> Expr
|
|
|
|
|
unsizedLiteralFor '1' = UniOp UniSub $ Number "'sd1"
|
|
|
|
|
unsizedLiteralFor ch = literalFor "'sd" ch
|
|
|
|
|
|
2020-06-06 03:40:59 +02:00
|
|
|
convertExpr :: Expr -> Expr
|
2020-06-15 03:43:32 +02:00
|
|
|
convertExpr (DimsFn fn (Right e)) =
|
|
|
|
|
DimsFn fn $ Right $ convertSizeExpr e
|
|
|
|
|
convertExpr (Concat exprs) =
|
|
|
|
|
Concat $ map convertSelfDeterminedExpr exprs
|
|
|
|
|
convertExpr (Repeat count exprs) =
|
|
|
|
|
Repeat count $ map convertSelfDeterminedExpr exprs
|
2020-06-06 03:40:59 +02:00
|
|
|
convertExpr (Number ['\'', ch]) =
|
2020-06-15 03:43:32 +02:00
|
|
|
unsizedLiteralFor ch
|
2019-03-19 18:40:25 +01:00
|
|
|
convertExpr other = other
|
2020-06-06 03:40:59 +02:00
|
|
|
|
2020-06-15 03:43:32 +02:00
|
|
|
convertSelfDeterminedExpr :: Expr -> Expr
|
|
|
|
|
convertSelfDeterminedExpr (Number ['\'', ch]) =
|
|
|
|
|
sizedLiteralFor ch
|
|
|
|
|
convertSelfDeterminedExpr other = other
|
|
|
|
|
|
|
|
|
|
convertStmt :: Stmt -> Stmt
|
|
|
|
|
convertStmt (Subroutine (fn @ (Ident ('$' : _))) (Args args [])) =
|
|
|
|
|
Subroutine fn (Args args' [])
|
|
|
|
|
where args' = map convertSelfDeterminedExpr args
|
|
|
|
|
convertStmt other = other
|
|
|
|
|
|
|
|
|
|
convertType :: Type -> Type
|
|
|
|
|
convertType (TypeOf e) = TypeOf $ convertSizeExpr e
|
|
|
|
|
convertType other = other
|
|
|
|
|
|
|
|
|
|
convertSizeExpr :: Expr -> Expr
|
|
|
|
|
convertSizeExpr (Mux cond e1 e2) =
|
|
|
|
|
Mux cond e1' e2'
|
2020-06-06 23:01:27 +02:00
|
|
|
where
|
2020-06-15 03:43:32 +02:00
|
|
|
e1' = convertSelfDeterminedExpr e1
|
|
|
|
|
e2' = convertSelfDeterminedExpr e2
|
|
|
|
|
convertSizeExpr e = convertSelfDeterminedExpr e
|