From 8102e18ee628716aad641dc80c88fd2371813462 Mon Sep 17 00:00:00 2001 From: qcorradi Date: Tue, 23 May 2023 10:25:56 +0100 Subject: [PATCH 1/4] Allow generate region from every standard Standard compliance fixes (Checked against Verilog 1995/2001/2005 and SystemVerilog 2017 A.4.2): Do not accept generate regions inside other generate regions Accept attributes on all generate items independently from where they appear Do not print lone semicolon in generate region Print a block in for generate to be compatible with Verilog 2001 --- src/Language/SystemVerilog/AST/GenItem.hs | 6 ++++-- src/Language/SystemVerilog/Parser/Parse.y | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Language/SystemVerilog/AST/GenItem.hs b/src/Language/SystemVerilog/AST/GenItem.hs index 930af6a..15108d5 100644 --- a/src/Language/SystemVerilog/AST/GenItem.hs +++ b/src/Language/SystemVerilog/AST/GenItem.hs @@ -36,14 +36,15 @@ instance Show GenItem where printf "case (%s)\n%s\nendcase" (show e) bodyStr where bodyStr = indent $ unlines' $ map showGenCase cs show (GenIf e a GenNull) = printf "if (%s) %s" (show e) (showBareBlock a) + -- showBlockedBranch avoids dangling else ambiguity show (GenIf e a b ) = printf "if (%s) %s\nelse %s" (show e) (showBlockedBranch a) (showBareBlock b) show (GenFor (x1, e1) c (x2, o2, e2) s) = printf "for (%s = %s; %s; %s %s %s) %s" x1 (show e1) (show c) x2 (show o2) (show e2) - (showBareBlock s) - show (GenNull) = ";" + (showBlockedBranch s) -- Verilog 2001 requires this to be a block + show (GenNull) = "" show (GenModuleItem item) = show item showBareBlock :: GenItem -> String @@ -51,6 +52,7 @@ showBareBlock (GenBlock x i) = printf "begin%s\n%s\nend" (if null x then "" else " : " ++ x) (indent $ show i) +showBareBlock (GenNull) = ";" showBareBlock item = show item showBlockedBranch :: GenItem -> String diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index 4367d5f..e1fb325 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -694,14 +694,15 @@ ModuleItems :: { [ModuleItem] } : {- empty -} { [] } | ";" ModuleItems { $2 } | MITrace ModuleItem ModuleItems { addMITrace $1 ($2 ++ $3) } - ModuleItem :: { [ModuleItem] } - : NonGenerateModuleItem { $1 } - | ConditionalGenerateConstruct { [Generate [$1]] } - | LoopGenerateConstruct { [Generate [$1]] } + : NonGenerateModuleItem { $1 } + | AttributeInstance ModuleItem { map (addMIAttr $1) $2 } | "generate" GenItems endgenerate { [Generate $2] } +NonGenerateModuleItemA :: { [ModuleItem] } + : NonGenerateModuleItem { $1 } + | AttributeInstance NonGenerateModuleItemA { map (addMIAttr $1) $2 } +-- This item covers module instantiations and all declarations NonGenerateModuleItem :: { [ModuleItem] } - -- This item covers module instantiations and all declarations : ModuleDeclTokens(";") {% mapM recordPartUsed $ parseDTsAsModuleItems $1 } | ParameterDecl(";") { map (MIPackageItem . Decl) $1 } | "defparam" LHSAsgns ";" { map (uncurry Defparam) $2 } @@ -715,8 +716,9 @@ NonGenerateModuleItem :: { [ModuleItem] } | TaskOrFunction { [MIPackageItem $1] } | NInputGateKW NInputGates ";" { map (\(a, b, c, d) -> NInputGate $1 a b c d) $2 } | NOutputGateKW NOutputGates ";" { map (\(a, b, c, d) -> NOutputGate $1 a b c d) $2 } - | AttributeInstance ModuleItem { map (addMIAttr $1) $2 } | AssertionItem { [AssertionItem $1] } + | ConditionalGenerateConstruct { [Generate [$1]] } + | LoopGenerateConstruct { [Generate [$1]] } AssignOption :: { AssignOption } : {- empty -} { AssignOptionNone } @@ -1448,11 +1450,8 @@ GenItems :: { [GenItem] } | GenItems GenItem { $1 ++ [$2] } GenItem :: { GenItem } - : MITrace GenBlock { uncurry GenBlock $2 } - | MITrace NonGenerateModuleItem { genItemsToGenItem $ map GenModuleItem $ addMITrace $1 $2 } - | MITrace "generate" GenItems "endgenerate" { genItemsToGenItem $3 } - | MITrace ConditionalGenerateConstruct { $2 } - | MITrace LoopGenerateConstruct { $2 } + : MITrace GenBlock { uncurry GenBlock $2 } + | MITrace NonGenerateModuleItemA { genItemsToGenItem $ map GenModuleItem $ addMITrace $1 $2 } ConditionalGenerateConstruct :: { GenItem } : "if" "(" Expr ")" GenItemOrNull "else" GenItemOrNull { GenIf $3 $5 $7 } | "if" "(" Expr ")" GenItemOrNull %prec NoElse { GenIf $3 $5 GenNull } From fb2f3005eb6c5c088c75bdb30594d38a99552a25 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 31 Jul 2023 22:58:32 -0400 Subject: [PATCH 2/4] undoing some minor stylistic changes --- src/Language/SystemVerilog/Parser/Parse.y | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index e1fb325..4226b38 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -694,15 +694,16 @@ ModuleItems :: { [ModuleItem] } : {- empty -} { [] } | ";" ModuleItems { $2 } | MITrace ModuleItem ModuleItems { addMITrace $1 ($2 ++ $3) } + ModuleItem :: { [ModuleItem] } - : NonGenerateModuleItem { $1 } + : NonGenerateModuleItem { $1 } | AttributeInstance ModuleItem { map (addMIAttr $1) $2 } | "generate" GenItems endgenerate { [Generate $2] } NonGenerateModuleItemA :: { [ModuleItem] } : NonGenerateModuleItem { $1 } | AttributeInstance NonGenerateModuleItemA { map (addMIAttr $1) $2 } --- This item covers module instantiations and all declarations NonGenerateModuleItem :: { [ModuleItem] } + -- This item covers module instantiations and all declarations : ModuleDeclTokens(";") {% mapM recordPartUsed $ parseDTsAsModuleItems $1 } | ParameterDecl(";") { map (MIPackageItem . Decl) $1 } | "defparam" LHSAsgns ";" { map (uncurry Defparam) $2 } @@ -1450,7 +1451,7 @@ GenItems :: { [GenItem] } | GenItems GenItem { $1 ++ [$2] } GenItem :: { GenItem } - : MITrace GenBlock { uncurry GenBlock $2 } + : MITrace GenBlock { uncurry GenBlock $2 } | MITrace NonGenerateModuleItemA { genItemsToGenItem $ map GenModuleItem $ addMITrace $1 $2 } ConditionalGenerateConstruct :: { GenItem } : "if" "(" Expr ")" GenItemOrNull "else" GenItemOrNull { GenIf $3 $5 $7 } From 0102e4a915bcebc5430dd3ea7f923fb3dfdc5a5c Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 31 Jul 2023 22:58:50 -0400 Subject: [PATCH 3/4] don't output nested generate/endgenerate regions --- src/Language/SystemVerilog/AST/GenItem.hs | 4 ++-- src/Language/SystemVerilog/AST/ModuleItem.hs | 5 +++++ src/Language/SystemVerilog/AST/ModuleItem.hs-boot | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Language/SystemVerilog/AST/GenItem.hs b/src/Language/SystemVerilog/AST/GenItem.hs index 15108d5..1f7d1a1 100644 --- a/src/Language/SystemVerilog/AST/GenItem.hs +++ b/src/Language/SystemVerilog/AST/GenItem.hs @@ -17,7 +17,7 @@ import Language.SystemVerilog.AST.ShowHelp import Language.SystemVerilog.AST.Expr (Expr) import Language.SystemVerilog.AST.Op (AsgnOp) import Language.SystemVerilog.AST.Type (Identifier) -import {-# SOURCE #-} Language.SystemVerilog.AST.ModuleItem (ModuleItem) +import {-# SOURCE #-} Language.SystemVerilog.AST.ModuleItem (ModuleItem, showGenModuleItem) data GenItem = GenBlock Identifier [GenItem] @@ -45,7 +45,7 @@ instance Show GenItem where x2 (show o2) (show e2) (showBlockedBranch s) -- Verilog 2001 requires this to be a block show (GenNull) = "" - show (GenModuleItem item) = show item + show (GenModuleItem item) = showGenModuleItem item showBareBlock :: GenItem -> String showBareBlock (GenBlock x i) = diff --git a/src/Language/SystemVerilog/AST/ModuleItem.hs b/src/Language/SystemVerilog/AST/ModuleItem.hs index 1c69b14..e277ce5 100644 --- a/src/Language/SystemVerilog/AST/ModuleItem.hs +++ b/src/Language/SystemVerilog/AST/ModuleItem.hs @@ -16,6 +16,7 @@ module Language.SystemVerilog.AST.ModuleItem , AssignOption (..) , Severity (..) , AssertionItem (..) + , showGenModuleItem ) where import Data.List (intercalate) @@ -96,6 +97,10 @@ showModportDecl (dir, ident, e) = then printf "%s %s" (show dir) ident else printf "%s .%s(%s)" (show dir) ident (show e) +showGenModuleItem :: ModuleItem -> String +showGenModuleItem (Generate genItems) = show genItems +showGenModuleItem item = show item + type PortBinding = (Identifier, Expr) type ModportDecl = (Direction, Identifier, Expr) diff --git a/src/Language/SystemVerilog/AST/ModuleItem.hs-boot b/src/Language/SystemVerilog/AST/ModuleItem.hs-boot index 9a3054b..1c17dfb 100644 --- a/src/Language/SystemVerilog/AST/ModuleItem.hs-boot +++ b/src/Language/SystemVerilog/AST/ModuleItem.hs-boot @@ -1,7 +1,10 @@ module Language.SystemVerilog.AST.ModuleItem ( ModuleItem + , showGenModuleItem ) where data ModuleItem instance Eq ModuleItem instance Show ModuleItem + +showGenModuleItem :: ModuleItem -> String From 519dbbeee13747f9224f698a103564ec1883a825 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 31 Jul 2023 23:00:47 -0400 Subject: [PATCH 4/4] restore distinction between generate and non-generate items --- src/Language/SystemVerilog/Parser/Parse.y | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index 4226b38..0041a88 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -697,6 +697,8 @@ ModuleItems :: { [ModuleItem] } ModuleItem :: { [ModuleItem] } : NonGenerateModuleItem { $1 } + | ConditionalGenerateConstruct { [Generate [$1]] } + | LoopGenerateConstruct { [Generate [$1]] } | AttributeInstance ModuleItem { map (addMIAttr $1) $2 } | "generate" GenItems endgenerate { [Generate $2] } NonGenerateModuleItemA :: { [ModuleItem] } @@ -718,8 +720,6 @@ NonGenerateModuleItem :: { [ModuleItem] } | NInputGateKW NInputGates ";" { map (\(a, b, c, d) -> NInputGate $1 a b c d) $2 } | NOutputGateKW NOutputGates ";" { map (\(a, b, c, d) -> NOutputGate $1 a b c d) $2 } | AssertionItem { [AssertionItem $1] } - | ConditionalGenerateConstruct { [Generate [$1]] } - | LoopGenerateConstruct { [Generate [$1]] } AssignOption :: { AssignOption } : {- empty -} { AssignOptionNone } @@ -1453,6 +1453,8 @@ GenItems :: { [GenItem] } GenItem :: { GenItem } : MITrace GenBlock { uncurry GenBlock $2 } | MITrace NonGenerateModuleItemA { genItemsToGenItem $ map GenModuleItem $ addMITrace $1 $2 } + | MITrace ConditionalGenerateConstruct { $2 } + | MITrace LoopGenerateConstruct { $2 } ConditionalGenerateConstruct :: { GenItem } : "if" "(" Expr ")" GenItemOrNull "else" GenItemOrNull { GenIf $3 $5 $7 } | "if" "(" Expr ")" GenItemOrNull %prec NoElse { GenIf $3 $5 GenNull }