diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index a007e03..47aacd2 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -557,11 +557,11 @@ traverseExprsM' strat exprMapper = moduleItemMapper a'' <- traverseAssertionExprsM exprMapper a' return $ AssertionItem (mx, a'') - genItemMapper (GenFor (x1, e1) cc (x2, op2, e2) mn subItems) = do + genItemMapper (GenFor (n1, x1, e1) cc (x2, op2, e2) mn subItems) = do e1' <- exprMapper e1 e2' <- exprMapper e2 cc' <- exprMapper cc - return $ GenFor (x1, e1') cc' (x2, op2, e2') mn subItems + return $ GenFor (n1, x1, e1') cc' (x2, op2, e2') mn subItems genItemMapper (GenIf e i1 i2) = do e' <- exprMapper e return $ GenIf e' i1 i2 diff --git a/src/Language/SystemVerilog/AST/GenItem.hs b/src/Language/SystemVerilog/AST/GenItem.hs index 929e9c2..23eabe9 100644 --- a/src/Language/SystemVerilog/AST/GenItem.hs +++ b/src/Language/SystemVerilog/AST/GenItem.hs @@ -22,7 +22,7 @@ import {-# SOURCE #-} Language.SystemVerilog.AST.ModuleItem (ModuleItem) data GenItem = GenBlock (Maybe Identifier) [GenItem] | GenCase Expr [GenCase] (Maybe GenItem) - | GenFor (Identifier, Expr) Expr (Identifier, AsgnOp, Expr) (Maybe Identifier) [GenItem] + | GenFor (Bool, Identifier, Expr) Expr (Identifier, AsgnOp, Expr) (Maybe Identifier) [GenItem] | GenIf Expr GenItem GenItem | GenNull | GenModuleItem ModuleItem @@ -40,8 +40,9 @@ instance Show GenItem where (maybe "" (indent . indent . show) md) show (GenIf e a GenNull) = printf "if (%s) %s" (show e) (show a) show (GenIf e a b ) = printf "if (%s) %s\nelse %s" (show e) (show a) (show b) - show (GenFor (x1, e1) c (x2, o2, e2) mx is) = - printf "for (%s = %s; %s; %s %s %s) %s" + show (GenFor (new, x1, e1) c (x2, o2, e2) mx is) = + printf "for (%s%s = %s; %s; %s %s %s) %s" + (if new then "genvar " else "") x1 (show e1) (show c) x2 (show o2) (show e2) diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index ba10f5e..57edff8 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -432,6 +432,11 @@ ModuleItems :: { [ModuleItem] } | ModuleItems ";" { $1 } ModuleItem :: { [ModuleItem] } + : NonGenerateModuleItem { $1 } + | ConditionalGenerateConstruct { [Generate [$1]] } + | LoopGenerateConstruct { [Generate [$1]] } + | "generate" GenItems "endgenerate" { [Generate $2] } +NonGenerateModuleItem :: { [ModuleItem] } -- This item covers module instantiations and all declarations : DeclTokens(";") { parseDTsAsModuleItems $1 } | ParameterDecl(ParameterDeclKW, ";") { map MIDecl $1 } @@ -440,7 +445,6 @@ ModuleItem :: { [ModuleItem] } | AlwaysKW Stmt { [AlwaysC $1 $2] } | "initial" Stmt { [Initial $2] } | "genvar" Identifiers ";" { map Genvar $2 } - | "generate" GenItems "endgenerate" { [Generate $2] } | "modport" ModportItems ";" { map (uncurry Modport) $2 } | PackageItem { [MIPackageItem $1] } | NInputGateKW NInputGates ";" { map (\(a, b, c) -> NInputGate $1 a b c) $2 } @@ -859,12 +863,16 @@ GenItems :: { [GenItem] } | GenItems GenItem { $1 ++ [$2] } GenItem :: { GenItem } + : GenBlock { uncurry GenBlock $1 } + | NonGenerateModuleItem { genItemsToGenItem $ map GenModuleItem $1 } + | ConditionalGenerateConstruct { $1 } + | LoopGenerateConstruct { $1 } +ConditionalGenerateConstruct :: { GenItem } : "if" "(" Expr ")" GenItemOrNull "else" GenItemOrNull { GenIf $3 $5 $7 } | "if" "(" Expr ")" GenItemOrNull %prec NoElse { GenIf $3 $5 GenNull } - | GenBlock { uncurry GenBlock $1 } | "case" "(" Expr ")" GenCases opt(GenCaseDefault) "endcase" { GenCase $3 $5 $6 } - | "for" "(" Identifier "=" Expr ";" Expr ";" GenvarIteration ")" GenBlock { (uncurry $ GenFor ($3, $5) $7 $9) $11 } - | ModuleItem { genItemsToGenItem $ map GenModuleItem $1 } +LoopGenerateConstruct :: { GenItem } + : "for" "(" GenvarInitialization ";" Expr ";" GenvarIteration ")" GenBlock { (uncurry $ GenFor $3 $5 $7) $9 } GenBlock :: { (Maybe Identifier, [GenItem]) } : "begin" opt(Tag) GenItems "end" opt(Tag) { (combineTags $2 $5, $3) } @@ -879,6 +887,10 @@ GenCase :: { GenCase } GenCaseDefault :: { GenItem } : "default" opt(":") GenItemOrNull { $3 } +GenvarInitialization :: { (Bool, Identifier, Expr) } + : "genvar" Identifier "=" Expr { (True , $2, $4) } + | Identifier "=" Expr { (False, $1, $3) } + GenvarIteration :: { (Identifier, AsgnOp, Expr) } : Identifier AsgnOp Expr { ($1, $2, $3) } | IncOrDecOperator Identifier { ($2, AsgnOp $1, Number "1") }