mirror of https://github.com/zachjs/sv2v.git
wildcard conversion uses simple equality if trivially possible
This commit is contained in:
parent
0fb97f2381
commit
c005e5c6ae
|
|
@ -15,22 +15,70 @@
|
||||||
- 3. Otherwise, the result is `1'b1`.
|
- 3. Otherwise, the result is `1'b1`.
|
||||||
-
|
-
|
||||||
- `!=?` is simply converted as the logical negation of `==?`, which is
|
- `!=?` is simply converted as the logical negation of `==?`, which is
|
||||||
- converted as described above.
|
-
|
||||||
|
- TODO: For code using actual wildcard patterns, this conversion produces code
|
||||||
|
- which is not synthesizable.
|
||||||
|
-
|
||||||
|
- The conversion for `inside` produces wildcard equality comparisons as per the
|
||||||
|
- SystemVerilog specification. However, many usages of `inside` don't depend on
|
||||||
|
- the wildcard behavior. To avoid generating needlessly complex output, this
|
||||||
|
- conversion use the standard equality operator if the pattern obviously
|
||||||
|
- contains no wildcard bits.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
module Convert.Wildcard (convert) where
|
module Convert.Wildcard (convert) where
|
||||||
|
|
||||||
|
import Control.Monad.State
|
||||||
|
import qualified Data.Map.Strict as Map
|
||||||
|
|
||||||
import Convert.Traverse
|
import Convert.Traverse
|
||||||
import Language.SystemVerilog.AST
|
import Language.SystemVerilog.AST
|
||||||
|
|
||||||
convert :: [AST] -> [AST]
|
type Patterns = Map.Map Identifier String
|
||||||
convert =
|
|
||||||
map $
|
|
||||||
traverseDescriptions $ traverseModuleItems $
|
|
||||||
traverseExprs $ traverseNestedExprs convertExpr
|
|
||||||
|
|
||||||
convertExpr :: Expr -> Expr
|
convert :: [AST] -> [AST]
|
||||||
convertExpr (BinOp WEq l r) =
|
convert = map $ traverseDescriptions convertDescription
|
||||||
|
|
||||||
|
convertDescription :: Description -> Description
|
||||||
|
convertDescription =
|
||||||
|
scopedConversion traverseDeclM traverseModuleItemM traverseStmtM Map.empty
|
||||||
|
|
||||||
|
traverseDeclM :: Decl -> State Patterns Decl
|
||||||
|
traverseDeclM decl = do
|
||||||
|
case decl of
|
||||||
|
Param Localparam _ x (Number n) -> modify $ Map.insert x n
|
||||||
|
_ -> return ()
|
||||||
|
let mi = MIPackageItem $ Decl decl
|
||||||
|
mi' <- traverseModuleItemM mi
|
||||||
|
let MIPackageItem (Decl decl') = mi'
|
||||||
|
return decl'
|
||||||
|
|
||||||
|
traverseModuleItemM :: ModuleItem -> State Patterns ModuleItem
|
||||||
|
traverseModuleItemM = traverseExprsM traverseExprM
|
||||||
|
|
||||||
|
traverseStmtM :: Stmt -> State Patterns Stmt
|
||||||
|
traverseStmtM = traverseStmtExprsM traverseExprM
|
||||||
|
|
||||||
|
traverseExprM :: Expr -> State Patterns Expr
|
||||||
|
traverseExprM = traverseNestedExprsM $ stately convertExpr
|
||||||
|
|
||||||
|
isPlainPattern :: Patterns -> Expr -> Bool
|
||||||
|
isPlainPattern _ (Number n) =
|
||||||
|
not $ any isWildcardChar n
|
||||||
|
where
|
||||||
|
isWildcardChar :: Char -> Bool
|
||||||
|
isWildcardChar = flip elem "xzXZ?"
|
||||||
|
isPlainPattern patterns (Ident x) =
|
||||||
|
case Map.lookup x patterns of
|
||||||
|
Nothing -> False
|
||||||
|
Just n -> isPlainPattern patterns (Number n)
|
||||||
|
isPlainPattern _ _ = False
|
||||||
|
|
||||||
|
convertExpr :: Patterns -> Expr -> Expr
|
||||||
|
convertExpr patterns (BinOp WEq l r) =
|
||||||
|
if isPlainPattern patterns r
|
||||||
|
then BinOp Eq l r
|
||||||
|
else
|
||||||
BinOp BitAnd couldMatch $
|
BinOp BitAnd couldMatch $
|
||||||
BinOp BitOr noExtraXZs $
|
BinOp BitOr noExtraXZs $
|
||||||
Number "1'bx"
|
Number "1'bx"
|
||||||
|
|
@ -44,8 +92,8 @@ convertExpr (BinOp WEq l r) =
|
||||||
-- Step #2: extra X or Z
|
-- Step #2: extra X or Z
|
||||||
noExtraXZs = BinOp TEq lxlxrxr rxr
|
noExtraXZs = BinOp TEq lxlxrxr rxr
|
||||||
lxlxrxr = BinOp BitXor lxl rxr
|
lxlxrxr = BinOp BitXor lxl rxr
|
||||||
convertExpr (BinOp WNe l r) =
|
convertExpr patterns (BinOp WNe l r) =
|
||||||
UniOp LogNot $
|
UniOp LogNot $
|
||||||
convertExpr $
|
convertExpr patterns $
|
||||||
BinOp WEq l r
|
BinOp WEq l r
|
||||||
convertExpr other = other
|
convertExpr _ other = other
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue