diff --git a/src/Convert.hs b/src/Convert.hs index 81f6713..c7df96b 100644 --- a/src/Convert.hs +++ b/src/Convert.hs @@ -20,6 +20,7 @@ import qualified Convert.Interface import qualified Convert.IntTypes import qualified Convert.KWArgs import qualified Convert.Logic +import qualified Convert.Mux import qualified Convert.NamedBlock import qualified Convert.NestPI import qualified Convert.Package @@ -47,6 +48,7 @@ phases excludes = , Convert.Enum.convert , Convert.IntTypes.convert , Convert.KWArgs.convert + , Convert.Mux.convert , Convert.PackedArray.convert , Convert.StarPort.convert , Convert.StmtBlock.convert diff --git a/src/Convert/Mux.hs b/src/Convert/Mux.hs new file mode 100644 index 0000000..bf159bc --- /dev/null +++ b/src/Convert/Mux.hs @@ -0,0 +1,65 @@ +{- sv2v + - Author: Zachary Snow + - + - Elaboration of ternary expressions where the condition references a + - localparam. + - + - Our conversions generate a lot of ternary expressions. This conversion + - attempts to make the code output a bit cleaner. Note that we can only do this + - simplification on localparams because parameters can be overridden at + - instantiation. + - + - This conversion applies the heuristic that it will only make substitutions + - into a ternary condition if making substitutions immediately enables the + - expression to be simplified further. + -} + +module Convert.Mux (convert) where + +import Control.Monad.State +import qualified Data.Map.Strict as Map + +import Convert.Traverse +import Language.SystemVerilog.AST + +type Info = Map.Map Identifier Expr + +convert :: [AST] -> [AST] +convert = map $ traverseDescriptions convertDescription + +convertDescription :: Description -> Description +convertDescription = + scopedConversion traverseDeclM traverseModuleItemM traverseStmtM Map.empty + +traverseDeclM :: Decl -> State Info Decl +traverseDeclM decl = do + case decl of + Localparam _ x e -> modify $ Map.insert x e + _ -> return () + return decl + +traverseModuleItemM :: ModuleItem -> State Info ModuleItem +traverseModuleItemM item = traverseExprsM traverseExprM item + +traverseStmtM :: Stmt -> State Info Stmt +traverseStmtM stmt = traverseStmtExprsM traverseExprM stmt + +traverseExprM :: Expr -> State Info Expr +traverseExprM = traverseNestedExprsM $ stately convertExpr + +convertExpr :: Info -> Expr -> Expr +convertExpr info (Mux cc aa bb) = + if before == after + then Mux cc aa bb + else simplify $ Mux after aa bb + where + before = traverseNestedExprs substitute (simplify cc) + after = simplify before + substitute :: Expr -> Expr + substitute (Ident x) = + case Map.lookup x info of + Nothing -> Ident x + Just e-> e + substitute other = other +convertExpr _ other = other + diff --git a/src/Language/SystemVerilog/AST/Expr.hs b/src/Language/SystemVerilog/AST/Expr.hs index 264ff4c..6db0719 100644 --- a/src/Language/SystemVerilog/AST/Expr.hs +++ b/src/Language/SystemVerilog/AST/Expr.hs @@ -125,6 +125,7 @@ simplify (orig @ (Call Nothing "$clog2" (Args [Just (Number n)] []))) = case readNumber n of Nothing -> orig Just x -> Number $ show $ clog2 x +simplify (Mux (Number "0") e _) = e simplify (Mux (BinOp Ge c1 c2) e1 e2) = case (c1', c2') of (Number a, Number b) -> diff --git a/sv2v.cabal b/sv2v.cabal index 2ecf0e8..9be8a95 100644 --- a/sv2v.cabal +++ b/sv2v.cabal @@ -64,6 +64,7 @@ executable sv2v Convert.IntTypes Convert.KWArgs Convert.Logic + Convert.Mux Convert.NamedBlock Convert.NestPI Convert.Package