Foreach.hs 1.26 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
{- sv2v
 - Author: Zachary Snow <zach@zachjs.com>
 -
 - Conversion for `foreach` loops.
 -
 - We simply convert these loops to a series of loops, with the bounds and
 - direction provided by the array dimension query system functions. Omitted
 - indices are skipped.
 -}

module Convert.Foreach (convert) where

import Convert.Traverse
import Language.SystemVerilog.AST

convert :: [AST] -> [AST]
convert =
    map $ traverseDescriptions $ traverseModuleItems $
    traverseStmts convertStmt

convertStmt :: Stmt -> Stmt
convertStmt (Foreach x idxs stmt) =
    (foldl (.) id $ map toLoop $ zip [1..] idxs) stmt
    where
25
        toLoop :: (Integer, Identifier) -> (Stmt -> Stmt)
26 27
        toLoop (_, "") = id
        toLoop (d, i) =
28
            For (Left [idxDecl]) cmp [incr]
29
            where
30
                queryFn f = DimFn f (Right $ Ident x) (RawNum d)
31
                idxDecl = Variable Local (IntegerAtom TInteger Unspecified) i []
Zachary Snow committed
32
                    (queryFn FnLeft)
33
                cmp =
34
                    Mux (BinOp Eq (queryFn FnIncrement) (RawNum 1))
35 36 37 38
                        (BinOp Ge (Ident i) (queryFn FnRight))
                        (BinOp Le (Ident i) (queryFn FnRight))
                incr = (LHSIdent i, AsgnOp Sub, queryFn FnIncrement)
convertStmt other = other