2019-08-30 06:11:57 +02:00
|
|
|
{- sv2v
|
|
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
-
|
|
|
|
|
- Verilog-2005 requires that for loops have have exactly one assignment in the
|
2020-02-24 04:30:17 +01:00
|
|
|
- initialization section. For procedural for loops, we pull the declarations
|
|
|
|
|
- out to a wrapping block, and convert all but one assignment to a preceding
|
|
|
|
|
- statement. If a for loop has no assignments or declarations, a dummy
|
|
|
|
|
- declaration is generated.
|
2019-08-30 06:11:57 +02:00
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
module Convert.ForDecl (convert) where
|
|
|
|
|
|
|
|
|
|
import Convert.Traverse
|
|
|
|
|
import Language.SystemVerilog.AST
|
|
|
|
|
|
|
|
|
|
convert :: [AST] -> [AST]
|
|
|
|
|
convert =
|
|
|
|
|
map $ traverseDescriptions $ traverseModuleItems $
|
2020-02-24 04:30:17 +01:00
|
|
|
traverseStmts convertStmt
|
2019-08-30 06:11:57 +02:00
|
|
|
|
|
|
|
|
convertStmt :: Stmt -> Stmt
|
2019-10-01 05:03:55 +02:00
|
|
|
convertStmt (For (Left []) cc asgns stmt) =
|
|
|
|
|
convertStmt $ For (Right []) cc asgns stmt
|
|
|
|
|
convertStmt (For (Right []) cc asgns stmt) =
|
2019-08-30 06:11:57 +02:00
|
|
|
convertStmt $ For inits cc asgns stmt
|
2019-10-01 05:03:55 +02:00
|
|
|
where inits = Left [dummyDecl (Just $ Number "0")]
|
|
|
|
|
convertStmt (orig @ (For (Right [_]) _ _ _)) = orig
|
2019-08-30 06:11:57 +02:00
|
|
|
|
2019-10-01 05:03:55 +02:00
|
|
|
convertStmt (For (Left inits) cc asgns stmt) =
|
|
|
|
|
Block Seq "" decls $
|
|
|
|
|
initAsgns ++
|
|
|
|
|
[For (Right [(lhs, expr)]) cc asgns stmt]
|
2019-08-30 06:11:57 +02:00
|
|
|
where
|
2019-10-01 05:03:55 +02:00
|
|
|
splitDecls = map splitDecl inits
|
2019-08-30 06:11:57 +02:00
|
|
|
decls = map fst splitDecls
|
|
|
|
|
initAsgns = map asgnStmt $ init $ map snd splitDecls
|
|
|
|
|
(lhs, expr) = snd $ last splitDecls
|
|
|
|
|
|
2019-10-01 05:03:55 +02:00
|
|
|
convertStmt (For (Right origPairs) cc asgns stmt) =
|
|
|
|
|
Block Seq "" [] $
|
|
|
|
|
initAsgns ++
|
|
|
|
|
[For (Right [(lhs, expr)]) cc asgns stmt]
|
2019-08-30 06:11:57 +02:00
|
|
|
where
|
|
|
|
|
(lhs, expr) = last origPairs
|
|
|
|
|
initAsgns = map asgnStmt $ init origPairs
|
|
|
|
|
|
|
|
|
|
convertStmt other = other
|
|
|
|
|
|
|
|
|
|
splitDecl :: Decl -> (Decl, (LHS, Expr))
|
|
|
|
|
splitDecl (Variable d t ident a (Just e)) =
|
|
|
|
|
(Variable d t ident a Nothing, (LHSIdent ident, e))
|
|
|
|
|
splitDecl other =
|
|
|
|
|
error $ "invalid for loop decl: " ++ show other
|
|
|
|
|
|
|
|
|
|
asgnStmt :: (LHS, Expr) -> Stmt
|
2020-02-01 21:52:52 +01:00
|
|
|
asgnStmt = uncurry $ Asgn AsgnOpEq Nothing
|
2019-08-30 06:11:57 +02:00
|
|
|
|
|
|
|
|
dummyDecl :: Maybe Expr -> Decl
|
|
|
|
|
dummyDecl = Variable Local (IntegerAtom TInteger Unspecified) "_sv2v_dummy" []
|